英文:
What is stored in a slice/array of funcs?
问题
在文档中似乎找不到答案。
给定一个切片:
var funcs []func()
底层的支持数组是什么?
起初我以为它会是一个函数指针的数组,但后来我发现这是可能的:
funcs = append(funcs, f.SomeFunc)
funcs[0]() // 在f上调用SomeFunc
其中f
是任何具有为其定义的方法/接收器函数的类型。
那么底层的实现是什么呢?
示例程序:
package main
import "fmt"
func PrintStandalone() {
fmt.Println("Standalone")
}
type Point struct {
x int
y int
}
func (p *Point) PrintPoint() {
fmt.Println("X: ", p.x, " Y: ", p.y)
}
type Coordinate struct {
lat int
long int
}
func (c Coordinate) PrintCoordinate() {
fmt.Println("Lat: ", c.lat, " Long: ", c.long)
}
func main() {
p := Point{x: 1, y: 2}
c := Coordinate{lat: 3, long: 4}
var funcs []func()
funcs = append(funcs, PrintStandalone)
funcs = append(funcs, p.PrintPoint)
funcs = append(funcs, c.PrintCoordinate)
for _, fn := range funcs {
fn()
}
p = Point{x: 5, y: 6}
c = Coordinate{lat: 7, long: 8}
for _, fn := range funcs {
fn()
}
}
运行此程序会打印:
Standalone
X: 1 Y: 2
Lat: 3 Long: 4
Standalone
X: 5 Y: 6
Lat: 3 Long: 4
这表明,根据接收器方法是通过指针还是通过值,函数是在“相同对象”上调用还是在其副本上调用。
英文:
I cannot seem to find an answer anywhere in the documentation
Given a slice like:
var funcs []func()
What is the underlying backing array?
At first I thought it would be an array of function pointers, but I have since seen that this is possible:
funcs = append(funcs, f.SomeFunc)
funcs[0]() // calls SomeFunc on the f
Where f
is any type that has a method/receiver function defined for it.
So what is the underlying implementation?
Example program
package main
import "fmt"
func PrintStandalone() {
fmt.Println("Standalone")
}
type Point struct {
x int
y int
}
func (p *Point) PrintPoint() {
fmt.Println("X: ", p.x, " Y: ", p.y)
}
type Coordinate struct {
lat int
long int
}
func (c Coordinate) PrintCoordinate() {
fmt.Println("Lat: ", c.lat, " Long: ", c.long)
}
func main() {
p := Point{x: 1, y: 2}
c := Coordinate{lat: 3, long: 4}
var funcs []func()
funcs = append(funcs, PrintStandalone)
funcs = append(funcs, p.PrintPoint)
funcs = append(funcs, c.PrintCoordinate)
for _, fn := range funcs {
fn()
}
p = Point{x: 5, y: 6}
c = Coordinate{lat: 7, long: 8}
for _, fn := range funcs {
fn()
}
}
When run, this program prints
Standalone
X: 1 Y: 2
Lat: 3 Long: 4
Standalone
X: 5 Y: 6
Lat: 3 Long: 4
Indicating that, depending on whether the receiver method is by pointer or by value, the function is called on the "same object" or on a copy of it.
答案1
得分: 2
"所以[]func()
的底层类型是什么?"
它的底层类型是func()
。
你似乎面临的概念问题是,在Go语言中,方法(method)实际上就是普通函数,只是多了一个不属于(调用)签名的接收者(receiver)。关于方法值的详细信息可以在这里找到:https://go.dev/ref/spec#Method_values。
英文:
> So what is the underlying type [of []func()
]?
It is func()
.
The conceptual problem you seem to face is that methods are (more or less) plain functions in Go just having an additional receiver that is not part of the (call) signature). Details on this method values can be found here https://go.dev/ref/spec#Method_values.
答案2
得分: 1
除了@Volker的答案之外,想象方法是返回闭包的函数可能也有所帮助。也就是说,
func (p *Point) PrintPoint() {
fmt.Println("X: ", p.x, " Y: ", p.y)
}
在概念上与
func PrintPoint(p *Point) func() {
func() {
fmt.Println("X: ", p.x, " Y: ", p.y)
}
}
是相同的。现在,p.PrintPoint
只是一个简单的函数调用 PrintPoint(&p)
,它返回一个 func()
类型,这正是你的切片应该保存的确切类型。闭包的语义也解释了为什么值接收器和指针接收器的行为方式是这样的。
英文:
In addition to @Volker's answer, it might also help to imagine methods as functions that return closures over their receiver. I.e.
func (p *Point) PrintPoint() {
fmt.Println("X: ", p.x, " Y: ", p.y)
}
is conceptually the same as
func PrintPoint(p *Point) func() {
func() {
fmt.Println("X: ", p.x, " Y: ", p.y)
}
}
Now p.PrintPoint
just becomes a simple function invocation PrintPoint(&p)
which returns a func()
-- the exact type your slice is supposed to hold. The closure semantics also explain why value and pointer receivers behave the way they do.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论