Набор ворчливых жалоб на GoLang, основанный на моих тридцати с лишним годах работы программистом. Первая часть касается кортежей или, скорее, их отсутствия.
Люди, которые хорошо меня знают, в курсе, что последние несколько лет я использую GoLang в качестве основного языка программирования. Я писал об этом в 2021 году.
«Почему я пишу GoLang в 2021 году? Он делает то, что мне нужно для продуктивной работы | Середина"
Несколько проектов, которые я прототипировал в Go, впоследствии стали успешными компонентами крупных коммерческих систем. К сожалению, хотя я и программирую на работе, с годами количество часов программирования сократилось, больше архитектуры и дизайна, чем прямых рук на клавиатуре. Это изменилось за последний месяц, когда я сосредоточился на проверке концепции нового продукта, который мы создаем.
После успешной установки Go на моем рабочем компьютере, что немаловажно, если вы работаете на предприятии за брандмауэрами и с заблокированными рабочими столами, я был готов к программированию. Этот блог кристаллизует мой нынешний почти тридцатилетний опыт профессионального разработчика. Обычно я люблю программировать на Go, но бывают моменты, когда я поднимаю руки вверх.
Где мои кортежи?
Что вы имеете в виду, говоря, что у go есть кортежи в качестве возвращаемых типов? На самом деле это не так. У него есть псевдокортежи, которые они могут использовать только в очень специфических обстоятельствах специального назначения, и даже сопоставление с образцом очень ограничено.
Почему функция не определяется как (кортеж) -> (кортеж), это позволяет создавать естественные цепочки выражений и во многих случаях устраняет необходимость в специальной обработке ошибок. Представьте, что вы могли бы написать
func f( ) (int,error) {} func g(int, error) (int,error) {} i, error := G( f() )
Вместо
i, err := f() j, err:= g( I, err )
Or
func h( x (int,error), s string) string
Вы могли бы написать
s := h( f(), “hello”)
Затем расширение
x := f(g())
где x — кортеж (int, error), тогда
i, err := x
Становится действительным. С «настоящими» кортежами также исчезают многие случаи, когда сегодня вам нужна небольшая структура. Если сопровождающие go не хотят добавлять в язык новую конструкцию, даже если она уже существует в рудиментарной форме, то добавление операций с индексами в struct почти то же самое.
type struct foo { a int b error } x := foo{ 1, nil} x[0] == 1 x[1] == nil
or
x.0 == 1 x.1 == nil
Добавить сопоставление с образцом
a, b := x
Затем создание () создания анонимной структуры из типов
x := (int,error){ 1, nil }
Это тот же синтаксис, который в настоящее время используется сигнатурами функций!
func() (int, error) { … }
return — это особый случай, когда {} не требуется. Немного углубившись в сигнатуры функций, мы назвали возвраты,
( x int, err error )
Это очень похоже на анонимную структуру! Так что сделай
struct { x int, err error } == ( x int, err error )
интересно,
func( x int, y int ) error
можно рассматривать как определение сопоставления анонимной структуры с анонимной структурой. С неявной деструктуризацией
func( x int, y int ) (z int, err error ) { return x + y, nil }
семантически совпадает с
func( __internal__ struct {x int, y int }( z int, err error ) { x, y := __internal__.x, __internal__.y var __return__ struct{x int, err error} __return__.z = x + y __return__.err = nil return __return__ }
Но почему? Ну, во-первых, это обращается к моему чувству последовательности, но также начинает открывать альтернативы обработке ошибок и цепочке функций, как указано выше.
Я также хотел бы отметить, что другие языки обрабатывают кортежи таким образом, на самом деле я был создателем этого стиля кортежа для Джулии.
Так иди, а ты? Подробнее в части 2