Почему в Go есть «новое»?

49

Я все еще озадачен тем, почему у нас newв Go.

Когда вы хотите создать экземпляр структуры, вы делаете

t := Thing{}

и вы можете получить указатель на новый экземпляр, выполнив

t := &Thing{}

Но есть и такая возможность:

t := new(Thing)

Этот последний кажется немного чуждым для остальной части языка. &Thing{}ясен и лаконичен, new(Thing)и в нем используются только конструкции, которые вы часто используете в других местах. Он также более расширяемый, так как вы можете изменить его на &Thing{3}или &Thing{Feets:7}.

По моему мнению, наличие дополнительного ключевого слова 1 стоит дорого, оно делает язык более сложным и добавляет того, что вы должны знать. И это может замаскировать новичков, что стоит за созданием структуры.

Это также делает еще одно зарезервированное слово.

Так в чем же причина new? Это иногда полезно? Должны ли мы использовать это?


1 : Да, я знаю, что это не ключевое слово на уровне грамматики, вы можете замаскировать его , но это не меняет того факта, что для разумного разработчика это зарезервированное слово.

Денис Сегюре
источник
3
«... Идти кодерам ...» - вот причина. F # / Haskell / и т.д.. очень чужды разработчикам C, и поэтому они набирают ~ 0 баллов. Скала сделала усилие, и теперь это более доступно и слышно о.
День
12
По тому же принципу Python и Ruby очень чужды разработчикам на C, поскольку они используют кучу незнакомых ключевых слов, «странных» синтаксических правил (где фигурные скобки?) И странных семантических концепций (генераторы «метаклассы», декораторы »). Тем не менее, они не получают ~ 0 тяги, совсем наоборот.
Сион
8
@Xion: вы смотрели на начальный темп роста Ruby? Потребовалось возрастов , чтобы получить , где он сейчас (18 лет, чтобы быть точным). Python еще старше (1991!).
Йоахим Зауэр
2
@AndresF. Некоторое сопротивление Скале не могло иметь ничего общего с языком. Будучи младшим программистом (25 лет), что-то в самом названии заставляет меня думать о чем-то вроде математического языка, такого как Matlab (о котором у меня плохие воспоминания), и действительно старого, такого как Fortran. Там никогда не было никакого желания даже взглянуть на это.
Изката
4
Примечание: новое не является ключевым словом в Go. Это встроенная функция.
Маниш Малик

Ответы:

44

Наверное, лучший способ спросить - это люди, которые над этим работают; именно то, что я сделал !

Tl; dr: он был там раньше makeи до &{}сих пор, и это все еще функция, которую можно использовать в некоторых ситуациях.

В основном, здесь приведены наиболее важные части:

Так в чем же причина нового? Это что-то полезное? Должны ли мы использовать это?

Вы не можете сделать это без нового

v := new(int)
*v++
fmt.Println(*v)

new не является заголовком Go, вы не найдете его часто используемым, но когда вам это нужно, он есть.

ура

Дейв

После другого ответа, показывающего такое решение:

vv := 0
v := &vv
*v++
fmt.Println(*v)

Я попросил дальнейших разъяснений:

Так что, в сущности, точка зрения Дейва не соответствует действительности?

Есть места, где неудобно вставлять новую переменную просто для того, чтобы взять ее адрес.

new (T) имеет непосредственное прямое значение, а не является многоэтапной идиомой.

Точка зрения Дейва только падает, если сама техническая возможность (обойтись без new) неотразима сама по себе.

Разве это не обсуждалось, потому что было просто очевидно, что в Go это должно быть, потому что это есть почти на каждом языке?

"Мы будем держать new?" обсуждение всплывает время от времени. Так как мы не можем взять его до Go 2, если я правильно понимаю Обещание, похоже, что от повторения цикла не так уж много; к тому моменту, когда Go 2 станет более продуманным, у нас может появиться несколько других и лучших идей ...

Крис

Это также там в основном по историческим причинам:

вам нужно рассмотреть историю проекта. Я думаю, что новое вводится в первую очередь, прежде чем есть сделать.

Это правда. На самом деле мы боролись некоторое время, прежде чем придумать идею сделать. Если вы посмотрите журналы репозитория, то увидите, что make появляется только в январе 2009 года, версия 9a924177598f.

Новая встроенная функция также предшествовала идее & {} для получения адреса составного литерала (и этот синтаксис в некотором смысле неправильный; вероятно, это должны быть (* T) {поля T}, но их было недостаточно причина поменять это).

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

Ян

Флориан Маргейн
источник
Я был бы рад видеть ссылки на другие "мы будем держать в курсе?" обсуждения, которые всплывают время от времени .
Денис Сегюре
Что-то мешает вам делать v := &(0)и пропускать переменную temp? (Я не знаю Go.)
Алекс Фейнман
3
@AlexFeinman Как 0буквальная константа, вы не можете взять ее адрес. Проблема может возникнуть, если вы тоже хотите определенный тип. Вот почему синтаксис похож &intили &int(0)может быть полезен (хотя и не задумывался о лучшем синтаксисе). Но делать это в две строки, как показал Коллинз, тоже хорошо ( vv := 0; v := &vv).
Денис Сегюре
14
«Так как мы не можем вынести это до Go 2» ... что, как все знают, никогда не произойдет, потому что Go 2считается вредным.
Мейсон Уилер
2
@MasonWheeler ты чуть не убил меня ... все еще смеясь над "Go 2 считается вредным" ... как ни странно, я говорил об этой статье сегодня за ланчем.
Даниэла Петрузалек