Search
Write a publication
Pull to refresh

Comments 10

Если пытаться писать «как в Java» с try/catch или тащить Python‑подходы, код превращается в громоздкие обёртки и цепочки ошибок, из‑за чего теряется главное преимущество Go — прозрачность и лёгкость сопровождения.

Честно говоря не замечал что из-за try/catch код превращается во что-то более громоздкое чем обработка ошибок в go...

try/catch в main() и пусть потом кто-то другой занимается извращенными видами секса в понимании того, что пошло не так в остальном коде на 100500 строк.
Видел такое неоднократно и сам подобным грешил на python. В Go есть паники и возможность поймать (при определенных условиях), но это ни разу не try/catch.А если лень прямо сейчас подумать как обработать ошибку - просто кидай ошибку в панику. Либо вернешься позже и допишешь либо оно паникнет и скорее всего это случится еще до прода.

Да, это более явно/очевидно. Но не менее громоздко. И понять где случилась ошибка не так уж трудно? Есть же stack trace.

По своему опыту не помню вообще никаких особых проблем с try/catch и определением где именно произошло исключение. Практически всегда есть трейс который прямо говорит что вот в таком то файле, на такой-то строке возникло такое-то исключение

Подход в го дисциплинирует, но вот назвать его менее громоздким что-то сложно

Проблема не сместом, а с тем почему там паникнуло.
Трейс содержит где эксепшен, и как к нему подобрались где, а почему (в частности на каких именно данных) - это подключайте гадание на кофейной гуще.
Если я пишу ошибку я чаще всего выведу еще и то, что не прошло парсинг или проверку.
Классика сюжета - вам ответ не API в Json вернул, а гейтвей в HTML - ну "очень информативно" получить трейс на падении парсинга JSON без того на чем оно споткнулось.

>defer ticker.Stop() // Гарантированно освобождаем ресурсы
...и почему я все время чувствую себя в time-machine?

Уже (лень искать с какой версии) даже time.After стало не грешно использовать без опасений утечки памяти.... Но, да, давайте продолжать пользоваться древними версиями языка и продолжать подстилать соломку там где уже давно не надо.

b.ResetTimer()

довцы в туже топку. Как завезли итераторы так завезли и итератор для бенчмарков. Но да надо же версию языка обновить, что бы об этом узанать.

...и почему я все время чувствую себя в time-machine?

в 1.24 ticker.Stop() не нужен?

Да. Но раньше это действительно было проблемой приводящей к утечкам памяти. Почему только писатели таких статей не удосужатся проверить актуальность такого рода проблем - для меня загадка. Ведь читают то, в частности, люди которые "немного" в теме.

Первый принцип идиоматики Go — простота и читаемость. Идиоматичный Go-код должен быть простым и понятным, без лишних абстракций. 

...

Среди сторонних библиотек выделяются для веб- и HTTP-API — лёгкие и быстрые gin или fiber. 

Игорь, мне кажется, что в сообществе Go веб-фреймворк gin не долюбливают из-за как раз таки лишних абстракций, присущих популярным фреймворкам из других языков программирования. Сам же я его нередко встречаю в вакансиях, но ни разу не приходилось использовать в продакшене.
Точно ли является его использование идиоматически с точки зрения Go?

"В Go принято держать проект в единой, но чётко организованной структуре"

пакет pkg/utils и в нем файл helpers.go

Пример структуры проекта лучше доработать, чтобы не распространять такие антипаттерны.

А меня напрягла тема с переиспользованием среза (slice), если в памяти среза foo хранятся указатели, то, пока жива ссылка на foo, GC не освободит занятую память.

type Foo struct {
  v []byte
}

func main() {
  foos := make([]Foo, 1_000)
  printAlloc() // 83 KB
  for i := 0; i < len(foos); i++ {
    foos[i] = Foo{
      v: make([]byte, 1024*1024),
    }
  }
  printAlloc() // 1024072 KB
  two := keepFristTwoElementsOnly(foos)
  runtime.GC() 
  printAlloc() // 1024072 KB
}

func keepFristTwoElementsOnly(foos []Foo) []Foo {
  return foos[:2]
}

Чтобы этой проблемы не было, можно сделать копию.

func keepFristTwoElementsOnly(foos []Foo) []Foo {
  res := make([]Foo, 2)
  copy(res, foos)
  return res
}

или руками ссылки поудалять

func keepFristTwoElementsOnly(foos []Foo) []Foo {
  for i := 2; i < len(foos); i++ {
    foos[i].v = nil
  }

  return foos[:2]
}

тут уже надо смотреть, если особо важна скорость выполнения операций, а i ближе к n, чем к нулю, то возможно рассмотреть использование только второго варианта. Он потребует перебора меньшего количества элементов

Sign up to leave a comment.