Go is still not good
Go всё ещё плох
Кратко: автор 10+ лет критикует Go за архитектурные ошибки, которые легко было избежать.
1. Ошибки: неверная область видимости
bar, err := foo()
if err != nil { … }
if err = foo2(); err != nil { … }
// err висит до конца функции, хотя нужен только в двух строках
Читателю приходится тратить время, выясняя, где err
ещё используется.
2. Два вида nil
var i interface{}
var s *S
fmt.Println(s == nil, i == nil, s == i) // true, true, false
i = s
fmt.Println(s == nil, i == nil, s == i) // true, false, true
Один «billion-dollar mistake» не хватило — сделали два.
3. Непереносимость
Условная компиляция через комментарии в начале файла — «аристотелевский» подход: теория без практики. Реальные проекты страдают.
4. append
без чёткого владения
a := []string{"hello", "world", "!"}
foo(a[:1]) // внутри append
fmt.Println(a) // результат зависит от капасити слайса
Поведение неочевидно и требует знания внутренностей.
5. defer
вместо RAII
В Java и Python ресурс закрывается автоматически при выходе из блока.
В Go приходится вручную писать defer foo.Close()
и гадать, какие ресурсы вообще требуют закрытия.