Pull to refresh

Comments 26

Значения по умолчанию для аргументов функций и полей структур. Просто дичайше этого не хватает.

В Go, если тебе нужно значение по умолчанию, то ты пишешь для этого отдельную функцию.
Например:
func add(a, b int) int {
   return a + b
}

func addOne(a int) int {
   return add(a, 1)
} 


Да, это увеличивает количество кода, и в начале было неудобно, но потом я ощутил преимущества такого подхода: большая предсказуемость и лучшая читаемость.

Например, когда ты читаешь код и видишь:
driver := app.getMysqlDriver()


То сразу понятно, о чем речь, а в случае:
driver := app.getDriver()
....
getDriver(for=mysql) driver{...}

для получения ответа приходится чутка копнуть, что на дистанции ухудшает читаемость.

Не уверен, что привёл лучшие примеры, но основная мысль понятна, думаю
UFO just landed and posted this here
Не очень ясен выигрыш от таких ломающих обратную совместимость изменений. На первый взгляд кажется, что удобства это не добавит, а код сломает очень многим.
Не стоит ли это решать индивидуально командам, когда устанавливают code style, просто подбирая подходящий набор linters?

Мне кажется, убирать какие-то неочевидные, но дублирующиеся чем-то ещё, или просто ненужные вещи они из языка действительно могут, особенно если это не часто используется людьми (хотя я и не согласен по поводу named return values).


Но вот изменять текущее поведение чего-то в языке — теперь уже вряд ли.


решить проблему видимости переменной цикла for при ее передачи в анонимную функцию внутри цикла

А в чем проблема?

> убрать named return values из функций и методов
К сожалению, предложение с try() полагается на существование этой фичи, так что вряд ли её уберут :). С другой стороны, лично мне не нравится не столько наличие named return values, сколько сочетание этой фичи с наличием return без аргументов. То есть, я всегда пишу явный список возвращаемых значений, даже если у них есть имена и я просто перечисляю их список в return :). Это позволяет убедиться в том, что я всегда возвращаю zero values в случае ошибок

Интересно почему try а не постфиксный оператор типа? Как в swift или rust.

Ну вы сравнили… Rust это другая вселенная. У них вопросительный знак это синтаксический сахар для работы с обобщённым типом Result, который в других языках известен как Option или Maybe. См. stackoverflow.com/a/42921174

Конечно, было бы круто, если бы в Go появились типы высших порядков, но это будет уже не Go, а Rust со сборкой мусора, или F#.
У них вопросительный знак это синтаксический сахар для работы с обобщённым типом Result, который в других языках известен как Option или Maybe.

Option и Result — совершенно разные типы, с разным назначением.
Option — явная проверка на null, может содержать либо объект обобщенного типа, либо None.
Result — тип-результат выполнения какого-либо действия, может содержать либо объект-результат успешного завершения дествия, либо объект-ошибку.

В дизайн-документе оно вообще смотрится странно. Если я не зарегистрирую var err error заранее — что произойдет? Куда вернется моя ошибка?
Реакция на драфт сообщества в виде кучи дизлайков ожидаема.

Дизлайков было бы еще больше, если бы они не заблокировали тред.
Я, кстати, не понимаю, зачем нужен try, если в Go2 планируется вот это?

Тоже смотрится внезапно, но по крайней мере выглядит органично с другими языковыми конструкциями.

Они check/handle запарятся пропихивать.
В ближайший релиз оборачиваение ошибок то не смогли пропихнуть, и много кто по существу за Is/As попинывает.
В фидбэках для try/catch даже отдельную категорию сделали.
За dep vs mod наверняка многие в недоумение. Стопудово "кость кинули", чтобы более-менее без конфликтов "остался только правильный вариант"

Я бы очень хотел иметь такую возможность:


var a int
var b int
c := (a = funcA()) + (b = funcB())
вроде так можно:
c := funcA() + funcB()

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

var a int
var b int

func f1() int {a=11;return a}
func f2() int {b=22;return b}

func main() {

	var c = f1() + f2()
	fmt.Println(a,b,c)              
}

Есть способы, конечно же! Хочется попроще...

Нет, это не простота языка, а банальное структурное программирование. В котором выражение не должно иметь побочных эффектов, а присваивание — не операция, а оператор.

К сожалению, большинство современных языков позаимствовало из C не только синтаксис, но и семантику, основанную на повсеместном использовании побочных эффектов и провоцирующую написание ненадёжного кода.

Очень хорошо, что авторы Go вернулись — хотя бы частично — к принципам «надёжного» программирования, сделав =, ++, — операторами, а не операциями. И небольшой рост объёма кода — совсем небольшая плата за увеличение его надёжности.

Достаточно высока вероятность пальнуть себе в ногу, если забыть, что операция присваивания ещё и значение возвращает.


Особенно это будет критично в if-statement (да, случай высосан из пальца, и не так страшен, как в C/C++/Java/..., потому что в в if разрешено только bool, но все равно неприятно):


if a = false {
        // ...
}

И после этого нужно постараться найти ошибку

В любом языке так. В if вряд ли стоит делать проверки типа a == false, это !a и только так.

Понятно, что мой прошлый пример высосан из пальца. А если так:


var x, y bool
// ...
if x = y {
        // ...
}

Подобная логика if со сравнением двух булевых переменных вполне имеет место быть

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

Мне не хватает тернарного оператора ?:
Иногда хотелось бы сделать что-то одной строкой, а не городить громоздкий if.
Sign up to leave a comment.

Articles