LINUX.ORG.RU

go переменные

 


0

6

Читаю про Go.

Поиск в Google выдает:
«В Go тип переменной ставится после имени из-за стремления к лаконичности и читаемости кода, а также для упрощения процесса вывода типов компилятором (синтаксис имя тип вместо тип имя), что делает код более понятным»

«Понятнее» конечно делает, если тип функции засунуть между аргументами функции и телом функции:

func CalculateDiscount(price float64, percentage float64) float64 {

Go поощряет использование коротких имен, особенно в случаях, когда их смысл легко понять из контекста.
Пример с habr.com (два варианта):

func countLines() int {
    // do stuff
    var linesCount int
    for i := 0; i < lines; i++ {
        linesCount += 1
    }
    return linesCount
}

func countLines() int {
    // do stuff
    var c int
    for i := 0; i < lines; i++ {
        c += 1
    }
    return c
}

★★

Последнее исправление: WinLin2 (всего исправлений: 5)
Ответ на: комментарий от LongLiveUbuntu

Массив указателей на функции, очевидно. *name[] это всегда массив указателей. Не путать с (*name)[] - это указатель на массив, тут звёздочка главнее (скобками придвинута к имени), а значит name в первую очередь указатель а дальше за скобками узнаётся на что именно.

Если бы ты хоть раз писал парсер сишных типов, понял бы что правила там вполне тривиальные и очевидные: то что справа смотрится раньше чем то что слева, порядок рассмотрения можно менять скобками.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 2)
Ответ на: комментарий от anonymous

а почему в жаве «пустую переменную» можно объявить как int linesCount и оно потом потребует чтобы значение присвоили, без всякой дичи с var? тут понятно, что в целом это дело исключительно привычки, но это не умаляет всратости синтаксиса.

borisych ★★★★★
()
Последнее исправление: borisych (всего исправлений: 1)
Ответ на: комментарий от borisych

дело исключительно привычки

но это не умаляет всратости синтаксиса

По мне так в Яве всратость.

В Go если переменна объявлена через var понятно, что она изначально пустая. А если нужно забиндить значение – := Можно ещё, конечно, изобразить var xs map[int]string = make(map[int]string) вместо xs := make(map[int]string), но зачем.

anonymous
()
Ответ на: комментарий от anonymous

А если нужно забиндить значение – :=

могу еще набор полезных операторов предложить:

8=o - писал джун, 8===o - нетленка сеньора, {0} - уничтожить после выхода из скоупа, (_._) - strong reference, (_0_) - weak reference

borisych ★★★★★
()
Ответ на: комментарий от anonymous

В Go если переменна объявлена через var понятно, что она изначально пустая. А если нужно забиндить значение – :=

в каком месте это «забиндить» происходит-то?

    var linesCount int
    for i := 0; i < lines; i++ {
        linesCount += 1
    }

вот пишем на жаве:

    int linesCount;
    for (int i = 0; i < 1000; i++) {
        linesCount += 1;
    }

оно говорит:

java: variable linesCount might not have been initialized

а в GO мы имеем то что имеем: где-то нужно писать так, а где-то вовсем иначе.

borisych ★★★★★
()
Ответ на: комментарий от firkax

блин будь * и [] однофиксны то скобки не нужны

ибо для пре было б
*[]name массив указателей vs []*name указатель на массив

ибо для пост было б
name[]* массив указателей vs name*[] указатель на массив

но в этом адке выбор между *name[] vs (*name)[] по забавным причинам не достаточной привычности(на начало 1970ых) в косвенные косвенности и даже желания избегать двойные косвенности удорожанием синтаксиса таковых конструкций

[upd] и более того костыльности int n[] как декларации (наряду с выделением памяти в случае n[literalInt]) и int[n] Ж)

qulinxao3 ★☆
()
Последнее исправление: qulinxao3 (всего исправлений: 2)
Ответ на: комментарий от firkax

настолько тривиальные что во втором издании Сяшки был подраздел главы алгоритмизирующий парсинг крокодила деклараций

по факту сяшка это строчно-ориентированный ассемблер :)

qulinxao3 ★☆
()
Ответ на: комментарий от ugoday

Go сразу стал бы годным языком? А если нет, к чему эта придирка?

ладно, сдаюсь, как в GO правильно писать for loop по int64? так:

func countLines() int {
    // do stuff
    var linesCount int
    var lines int64 = 1000000000000000000
    var i int64 = 0;
    for ; i < lines; i++ {
        linesCount += 1
    }
    return linesCount
}
borisych ★★★★★
()
Ответ на: комментарий от LongLiveUbuntu

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

firkax ★★★★★
()
Ответ на: комментарий от qulinxao3

С этим частично можно согласиться, однако:

Если всё сделать префиксным - непонятно как в эту конструкцию вписать аргументы функции, что-то типа int (int arg) funcname выглядит нелепо. Да и int [5] var тоже не особо норм. Хотя, может быть, это опрос привычки и если б я сразу такое увидел - было бы всё норм. Ещё надо вспомнить, что в имевшемся раньше Фортране размерности массивов тоже были справа (а указателей не было вообще), и наверно тоже не хотели это ломать.

Если всё сделать постфиксным - то тайпкасты будут записываться неочевидно. Сейчас тайпкасты к указателями выглядят нормально, а вот тайпкаст к массиву или фукнции - не очень, благо они обычно и не нужны. А так будет и с указателем сложно, а он уже нужен очень часто.

firkax ★★★★★
()
Ответ на: комментарий от GFORGX

Перевожу: автор возмущен неинтуитивностью го-синтаксиса объявления функций. Вся суть темы в установке кавычек вокруг слова «понятнее».

firkax ★★★★★
()
Ответ на: комментарий от qulinxao3

Уровень не падает, задачи становятся более другими и требуют более других навыков. Немногие сегодня способны самостоятельно выживать в дикой природе. Значит ли это, что мы, жители города, менее образованы, чем люди, до сих пор живущие племенами, охотой и земледелием?

korvin_ ★★★★★
()
Ответ на: комментарий от korvin_

эээ

есть целый жанр

Эпоха не решительности

не помню название по инопланетян прилетевших на землю и оказавшихся в среднем тупее (англоязычный автор - там видимо про паралель средней уровень матросов европейских кораблей при «апроприации» Индостана в 18-19 веках

ну и байка у Дробышевского про чукчу в начале 20 века которому было достаточно ознакомится с идеей букв что бы замутит свою систему знаков для фиксации ему нужных фактов при ведении бытовых хоз задач

в том и прикол что при отсутсвии отбирающего давления преимущество получают те кто не тратят энергию «зря» - т.е. при изобилии выгоднее преследовать чисто биологические цели :)(

qulinxao3 ★☆
()
Ответ на: комментарий от qulinxao3

Байки и сказки. Где статистика? Где исследования? Интернет, мой смартфон, медицину, образование и так далее, и тому подобное не чукчи придумали и реализовали, например. Кто тратит энергию «зря» — большой вопрос

korvin_ ★★★★★
()
Ответ на: комментарий от korvin_

Конечно, не в этом. Это вообще не работа, это автоматическое действие, которое не должно вызывать каких бы то ни было вопросов, проблем, траты сил. Если вызывает - значит не тот род занятий выбрал.

firkax ★★★★★
()
Ответ на: комментарий от ya-betmen

Обычное дело. Находятся любители мечтать: «какой хороший язык я разработал бы, если бы умел программировать». Но успешные языки успешны потому.что хорошо приспособлены для своего назначения, в том числе и синтаксис у них не случайный. При изучении нового языка полезно понять, почему он сделан таким.

Partisan ★★★★★
()
Ответ на: комментарий от korvin_

ооо вы и интегралы знаете?!

вопрос в отчуждении и сохранении «знания» ну и разделение труда и прочая тэхне

люди в «космос» могли и в до нашей эры вылезти - но не вылезли - и не потому что индивидуально были тупее(скорее наоборот) а потому что их софтуха меньше доверяла окружающим что делало почти не возможным «долговременные» контракты - не случайно были субботние года - да и вообще куча ритуализаций - т.е. коррелированные дебилы часто эффективней опортунизированных гениев

qulinxao3 ★☆
()
Ответ на: комментарий от firkax

Конечно, не в этом. Это вообще не работа, это автоматическое действие, которое не должно вызывать каких бы то ни было вопросов, проблем, траты сил. Если вызывает - значит не тот род занятий выбрал.

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

korvin_ ★★★★★
()
Ответ на: комментарий от firkax

А ты сравни один и тот же код на разных языках и всё увидишь.

Сравнивал много раз на разных языках.

Отличия там почти везде. В го же устроили мешанину надёргав из разных мест.

И? Тебя интересуют только строго уникальные языки, где ничего ниоткуда не надёргано?

korvin_ ★★★★★
()
Ответ на: комментарий от korvin_

Я про то что Си выглядит консистентным и последовательным. Паскаль тоже. Го же таким не выглядит - разные части его синтаксиса выглядят чужеродно друг к другу и смотрится это ужасно.

firkax ★★★★★
()
Ответ на: комментарий от firkax

За тебя машина ложку ко рту не подносит случайно когда ты ешь? Это примерно из той же серии действия.

Просто потому что такой машины пока нет. Но языки есть разные. Одни упрощают решение определённых задач в большей степени, чем другие, беря на себя больше забот.

korvin_ ★★★★★
()
Ответ на: комментарий от firkax

Я про то что Си выглядит консистентным и последовательным.

Ха-ха, смешно

Го же таким не выглядит - разные части его синтаксиса выглядят чужеродно друг к другу

Нет, не выглядят

korvin_ ★★★★★
()

Если тебе не с кем поговорить, то я вызывал Google Gemini за тебя, не благодари. Вот его ответ:


Понимаю твой скепсис. После C, C++ или Java синтаксис Go (имя тип) поначалу кажется вывернутым наизусть. Но авторы языка (Роб Пайк и Кен Томпсон) сделали это не просто ради того, чтобы «быть не как все».

Вот несколько аргументов, которые помогают понять эту логику:

1. Читаемость сложных объявлений

В C-подобных языках описание указателей на функции может превратиться в «кошмар спирали». Например, в C: int (*fp)(int (*ff)(int x, int y), int z);

В Go описание идет слева направо, как мы читаем: f func(func(int, int) int, int) int

Это избавляет от необходимости парсить выражение в разные стороны, чтобы понять, где имя, а где тип.

2. Упрощение парсинга для компилятора

Когда тип идет после имени, компилятору проще обрабатывать код без необходимости заглядывать далеко вперед (look-ahead). Это одна из причин, почему Go компилируется молниеносно. Если ты видишь слово var или func, ты сразу знаешь, что дальше будет имя объекта, а потом — всё остальное.


Про краткие имена (c вместо linesCount)

В Go действительно существует «культ» лаконичности, но у него есть свои правила приличия. Логика сообщества такая: «Чем меньше область видимости переменной, тем короче должно быть её имя».

Имя переменнойКогда использовать
i, j, kВ коротких циклах на 2–5 строк.
rЧасто используется для Reader, w для Writer.
errСтандарт для обработки ошибок.
linesCountЕсли переменная живет на протяжении 50+ строк кода или экспортируется из пакета.

Твой пример с Хабра наглядно показывает крайности. В функции на 5 строк переменная c (count) не создаст проблем, потому что её объявление и возврат видны одновременно на одном экране. Но если функция разрастется до 100 строк, c станет «магической буквой», и любой нормальный разработчик скажет, что это плохой код.

Важный нюанс: Короткие имена в Go работают только тогда, когда сам тип переменной или название функции уже объясняют суть. Если функция называется countLines, то очевидно, что она возвращает счетчик строк.


Почему тип функции «между» аргументами и телом?

Давай посмотрим на это с точки зрения математики или логики: func Название(Входные данные) Выходные данные { Тело }

Это похоже на описание преобразования: мы берем price и percentage, и на выходе получаем float64. В Go возвращаемых значений может быть несколько, и такая структура позволяет легко их перечислить:

func Divide(a, b int) (int, error) { ... }

Если бы тип возврата стоял в начале (как в Java/C), нам было бы сложнее быстро найти название функции в списке методов, так как названия типов имеют разную длину и «сдвигают» имена функций вправо.

Как тебе такая логика? Кажется ли она оправданной или «старый добрый» C-стиль всё равно нагляднее?

lovesan ★★☆
()