英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论