Go的方法语法的基本原理

时间:2012-03-18 14:15:03

标签: go

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

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

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

但为什么有一个额外的参数列表只是为了“接收器”,因为我认为它被称为?只做

,这不是一个更简单,更优雅的设计吗?
func Foo(s *SomeStruct, x int) { }

然后将s.Foo(5)转换为对函数Foo(s, 5)的调用?

4 个答案:

答案 0 :(得分:20)

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

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

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

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

答案 1 :(得分:7)

您的问题正确指出任何方法都是一种功能。但是,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关键字后跟标识符或(来区分。

答案 2 :(得分:3)

建议的替换在语义上与当前状态不同,即它不仅仅是语法上的改变。它将[尝试]自动创建恰好是函数的第一个参数的任何[本地包]类型的方法。考虑到Go的自动界面满意度规则概念的基本方法集如何,这很可能会导致一个大的混乱。

简而言之,我认为对Go语言的这种改变没有改善,同时损害了许多与方法和接口相关的很好的功能。

答案 3 :(得分:1)

可能是因为go不是Python。

另外,因为a function declared this way is not a method

您无法在对象包之外声明方法。所以我想方法和函数之间语法差异的主要原理是能够区分它们。