1 回答
TA贡献1898条经验 获得超8个赞
接收者只是函数的“普通”参数。普通参数可以是指针类型。如果是,则允许您nil作为参数传递,这是完全有效的。您需要记住的只是不要取消引用nil指针参数。这同样适用于特殊的接收器参数。如果它是一个指针,它可能是nil,你不能取消引用它。
规范:方法声明:
接收者是通过方法名称前面的额外参数部分指定的。
...该方法被称为绑定到它的接收者基类型,并且方法名称仅在type或的选择器中可见。T*T
允许nil接收器值不仅是不被禁止的,它还有实际用途。例如,请参阅测试嵌套结构中的 nil 值。
null在 Java 中,您也可以在对象上调用静态方法。确实你不能在 Go 中做同样的事情,因为 Go 没有像static,public等修饰符private。在 Go 中只有导出和非导出的方法(由它们的名字的后一个暗示)。
但是 Go 也提供了类似的东西:方法表达式和方法值。如果您有一个接收器类型的方法m,T则表达式T.m将是一个函数值,其签名包含m接收器类型“前缀”的参数和结果类型。
例如:
type Foo int
func (f Foo) Bar(s string) string { return fmt.Sprint(s, f) }
func main() {
fooBar := Foo.Bar // A function of type: func(Foo, string) string
res := fooBar(1, "Go")
fmt.Println(res)
}
Foo.Bar将是一个带有 type 的函数func (Foo, string) string,你可以像任何其他普通函数一样调用它;而且您还必须将接收器作为第一个参数传递。上面的应用程序输出(在Go Playground上试试):
Go1
稍微“前进”,我们不需要存储Foo.Bar在变量中,我们可以直接调用Foo.Bar:
fmt.Println(Foo.Bar(1, "Go"))
输出相同(在Go Playground上尝试)。现在这几乎看起来像staticJava 中的方法调用。
而作为“最后”步骤,当我们对自身的值(而不是类型标识符)使用上述表达式时Foo,我们会得到方法值,这会保存接收者,因此方法值的类型不包括接收者,它的签名将是方法的签名,我们可以调用它而无需传递接收者:
var f Foo = Foo(1)
bar := f.Bar
fmt.Println(bar("Go"))
这将再次输出相同的内容,请在Go Playground上尝试。
- 1 回答
- 0 关注
- 249 浏览
添加回答
举报
