英文:
Why are structure functions the same type as ordinary functions
问题
在以下代码中:
struct Struct.Test 的类型是 void func(),这个函数可以获取 Struct t 中的所有参数,为什么 Struct.func() 和 func() 的类型是相同的?
type Struct struct {
Val string
}
func (t *Struct) Test() {
println(t.Val)
}
func main() {
t := Struct{
Val: "Struct",
}
f := t.Test
f()
f = func() {
println("Hello world!")
}
f()
}
在这段代码中,Struct.func() 和 func() 的类型是相同的,都是 void func()。这是因为在 Go 语言中,方法和函数的类型是相同的,只是方法需要通过接收者来调用。在这个例子中,Test() 方法是一个带有接收者 t *Struct 的方法,它可以通过 t 来访问结构体 Struct 的成员变量。而 func() 是一个没有接收者的函数,它可以直接调用。尽管它们的调用方式不同,但它们的类型是相同的。
英文:
In following codes:
type of struct Struct.Test is void func(), the function can get all parameters in Struct t, why the types of Struct.func() and func() are the same
type Struct struct {
Val string
}
func (t *Struct) Test() {
println(t.Val)
}
func main() {
t := Struct{
Val: "Struct",
}
f := t.Test
f()
f = func() {
println("Hello world!")
}
f()
}
答案1
得分: 1
t.Test 是一个方法值:
> 如果表达式 x 的静态类型是 T,并且 M 是类型 T 的方法集中的方法,那么 x.M 被称为 方法值。方法值 x.M 是一个函数值,可以使用与调用 x.M 方法相同的参数进行调用。 表达式 x 在方法值的评估过程中被计算和保存;保存的副本随后在任何调用中作为接收器使用,这些调用可能在以后执行。
x.Test() 方法没有参数,所以 x.Test 是一个没有参数的函数。接收器 x 在内部被保存并在以后调用 x.Test 函数值时使用。它的类型将是 func(),所以 f 的类型也是 func(),你可以将任何类型为 func() 的值分配给它。
不要将方法值与方法表达式混淆:
> 如果 M 在类型 T 的方法集中,那么 T.M 是一个函数,可以像常规函数一样调用,参数与 M 的参数相同,只是在前面多了一个参数,该参数是方法的接收器。
方法表达式是应用在_类型_上的,而方法值是应用在_值_上的。方法表达式的结果是一个包含接收器类型的函数值(作为第一个参数),而方法值则不包含(接收器在内部保存)。
所以在你的情况下,方法表达式将是 (*Struct).Test(注意指针:Test() 有指针接收器),它是一个类型为 func(Struct) 的函数。可以像这样使用/调用它:
f2 := (*Struct).Test
f2(&t)
再次输出 Struct,在Go Playground上试一试。
英文:
t.Test is a method value:
> If the expression x has static type T and M is in the method set of type T, x.M is called a method value. The method value x.M is a function value that is callable with the same arguments as a method call of x.M. The expression x is evaluated and saved during the evaluation of the method value; the saved copy is then used as the receiver in any calls, which may be executed later.
The x.Test() method has no parameters, so x.Test is a function without parameters. The receiver x is saved internally and used when you call the x.Test function value later. Its type will be func(), so type of f is also func(), to which you can assign any value that also has a type of func().
Don't confuse method values with method expressions:
> If M is in the method set of type T, T.M is a function that is callable as a regular function with the same arguments as M prefixed by an additional argument that is the receiver of the method.
The method expression is "applied" on a type, while a method value is "applied" on a value. Method expression results in a function value that includes the receiver type (as the first parameter), method value does not (the receiver is saved internally).
So in your case the method expression would be (*Struct).Test (note the pointer: Test() has pointer receiver), and it's a function with type func(Struct). It may be used / called like this:
f2 := (*Struct).Test
f2(&t)
Which again outputs Struct, try it on the Go Playground.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论