Go的方法语法的基本原理

chi*_*gis 8 go

好吧,我不得不承认,我根本没有真正使用Go,但我确实只是观察到一些令我感到奇怪的东西,因为一种力求极简的语言和Go所做的所有好东西.如果背后没有合法的理由我会感到惊讶,所以这就是我在寻找的东西.

所以当你有一个方法时,你可以像这样定义它:

func (s *SomeStruct) Foo(x int) { }
Run Code Online (Sandbox Code Playgroud)

但为什么有一个额外的参数列表只是为了"接收器",因为我认为它被称为?它不会是一个更简单,更优雅的设计

func Foo(s *SomeStruct, x int) { }
Run Code Online (Sandbox Code Playgroud)

然后s.Foo(5)只是被转换为对函数的调用Foo(s, 5)

Eva*_*haw 20

方法基本上是特殊的,与常规函数不同.

  • 方法必须与接收器类型位于同一个包中.
  • 方法用于满足接口.
  • 接收器参数是唯一可能过载的参数.
  • 当匿名结构字段具有方法时,这些方法是"继承的".

根据您的建议,函数和方法之间的界限变得非常模糊,很难弄清楚如何解决上述问题.

也就是说,我认为设计一种具有多方法和接口的语言会非常有趣.但是,那种语言不会是Go.


小智 7

您的问题正确指出任何方法都是一个函数.但是,Go语言需要能够明确区分方法和功能.原因是方法具有功能所不具备的功能.Foo程序员需要选择是函数还是方法.

Go的极简主义意味着该语言仅定义了一小组关键字.Go作者可以选择一个新关键字,例如method,区分方法和函数:

method Foo(receiver *T, arg1 int) {}   // 'Foo' is a method, not a function
Run Code Online (Sandbox Code Playgroud)

围绕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
Run Code Online (Sandbox Code Playgroud)

基本思想是,对于解析器(和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) {}
Run Code Online (Sandbox Code Playgroud)

使解析器能够区分方法和函数:

func IDENTIFIER ...     This is going to be a function
func ( ...              This is going to be a method
Run Code Online (Sandbox Code Playgroud)

因此,解析器(以及Go程序员)可以根据func关键字后跟标识符还是后跟来进行区分(.