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, чем к нулю, то возможно рассмотреть использование только второго варианта. Он потребует перебора меньшего количества элементов
Секреты эффективного кодирования на Go для опытных и новичков: профайлинг, тесты, CI