Обоснование синтаксиса метода Go - PullRequest
8 голосов
/ 18 марта 2012

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

Поэтому, когда у вас есть метод, вы определяете его так:

func (s *SomeStruct) Foo(x int) { }

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

func Foo(s *SomeStruct, x int) { }

и затем s.Foo(5) просто преобразовать в вызов функции Foo(s, 5)?

Ответы [ 4 ]

20 голосов
/ 18 марта 2012

Методы принципиально особенные и отличаются от обычных функций.

  • Методы должны находиться в том же пакете, что и тип получателя.
  • Методы используются для удовлетворения интерфейсов.
  • Параметры получателя являются единственными параметрами, которые могут быть перегружены.
  • Когда у анонимных структурных полей есть методы, эти методы «наследуются».

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

Тем не менее, я думаю, что было бы действительно интересно разработать язык с мультиметодами и интерфейсами.Тем не менее, этот язык не будет Go.

7 голосов
/ 19 марта 2012

Ваш вопрос правильно указывает на то, что любой метод является функцией. Однако язык Go должен уметь четко различать методы и функции. Причина этого в том, что методы имеют функции, которых нет у функций. Программист должен сделать выбор: Foo - функция или метод.

Минимализм Go означает, что язык определяет только небольшой набор ключевых слов. Авторы Go могли бы выбрать новое ключевое слово, такое как method, чтобы отличать методы от функций:

method Foo(receiver *T, arg1 int) {}   // 'Foo' is a method, not a function

Оглядываясь на язык программирования Go, мы видим, что философия заключается в том, чтобы повторно использовать уже существующие ключевые слова, а не иметь отдельное ключевое слово для каждого случая. Ключевое слово for является хорошим примером такого подхода:

for {}                     // Infinite loop
for a>0 {a--}              // A while-do loop
for i := range channel {}  // Receive values from a channel
for i:=0; i<N; i++ {}      // C-style for loop

Основная идея состоит в том, что для синтаксического анализатора (и программистов на Go) для различения различных типов циклов for нет необходимости вводить новое ключевое слово, если параметры можно различить по синтаксису следует после ключевого слова for: ; := range identifier ..., их последовательного порядка и их наличия / отсутствия.

Ключевое слово func следует той же схеме. Может использоваться в нескольких контекстах:

  • определения функций: func f() {}
  • типы функций: type F func(int) int
  • определения методов: func (t T) SomeMethod() {}
  • закрытия: { ...; go func(){c<-1}(); ...}

С точки зрения минимализма, одно ключевое слово func проще и элегантнее, чем наличие нескольких ключевых слов.

Список дополнительных параметров только для получателя

func (t *T) Foo(x int) {}

позволяет анализатору различать методы и функции:

func IDENTIFIER ...     This is going to be a function
func ( ...              This is going to be a method

Таким образом, синтаксический анализатор (как и программисты на Go) может проводить различие в зависимости от того, за ключевым словом func следует идентификатор или (.

3 голосов
/ 18 марта 2012

Предлагаемая замена семантически не идентична текущему состоянию, то есть это не только синтаксическое изменение. Он [попытается] автоматически создать методы любого типа [локальный пакет], который оказывается первым параметром функции. Учитывая то, как фундаментальные наборы методов связаны с концепцией Go для правил автоматического удовлетворения интерфейса, вполне вероятно, что это приведет к большому беспорядку.

Короче говоря, я думаю, что такое изменение языка Go ничего не улучшит, но повредит многие его приятные функции, связанные с методами и интерфейсами.

1 голос
/ 18 марта 2012

Возможно, потому что go не является Python.

Кроме того, поскольку функция, объявленная таким образом, не является методом .

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...