在Go中,您可以将函数作为参数传递,例如callFunction(fn func)
。例如:
package main
import "fmt"
func example() {
fmt.Println("hello from example")
}
func callFunction(fn func) {
fn()
}
func main() {
callFunction(example)
}
但是当它是结构的成员时是否可以调用一个函数呢?以下代码将失败,但为您提供了我所谈论的示例:
package main
import "fmt"
type Example struct {
x int
y int
}
var example Example
func (e Example) StructFunction() {
fmt.Println("hello from example")
}
func callFunction(fn func) {
fn()
}
func main() {
callFunction(example.StructFunction)
}
(我知道我在该示例中尝试做的事情有点奇怪。我遇到的确切问题并没有很好地扩展为一个简单的示例,但这是我问题的本质。但是,我也对此很感兴趣从学术角度来看)
方法(不是“结构的成员”,而是任何命名类型的方法,不仅是结构)都是第一类值。Go 1.0.3尚未实现方法值,但是技巧版本(如即将发布的Go 1.1)具有支持方法值。在此处引用整个部分:
方法值
如果表达式
x
具有静态类型T
并且M
在type的方法集中T
,x.M
则称为方法值。方法值x.M
是可以使用与方法调用相同的参数调用的函数值x.M
。x
在评估方法值期间对表达式进行评估并保存;然后,保存的副本将在任何调用中用作接收者,稍后可能会执行。该类型
T
可以是接口或非接口类型。如在上述方法表达的讨论中,考虑一结构类型
T
与两个方法,Mv
,其接收器的类型为T
,和Mp
,其接收器的类型的*T
。type T struct { a int } func (tv T) Mv(a int) int { return 0 } // value receiver func (tp *T) Mp(f float32) float32 { return 1 } // pointer receiver var t T var pt *T func makeT() T
表达方式
t.Mv
产生一个类型的函数值
func(int) int
这两个调用是等效的:
t.Mv(7) f := t.Mv; f(7)
同样,表达式
pt.Mp
产生一个类型的函数值
func(float32) float32
与选择器一样,使用指针使用值接收器对非接口方法的引用将自动取消引用该指针:
pt.Mv
等效于(*pt).Mv
。与方法调用一样,使用可寻址值的指针接收器对非接口方法的引用将自动采用该值的地址:
t.Mv
等效于(&t).Mv
。f := t.Mv; f(7) // like t.Mv(7) f := pt.Mp; f(7) // like pt.Mp(7) f := pt.Mv; f(7) // like (*pt).Mv(7) f := t.Mp; f(7) // like (&t).Mp(7) f := makeT().Mp // invalid: result of makeT() is not addressable
尽管上面的示例使用了非接口类型,但是从接口类型的值创建方法值也是合法的。
var i interface { M(int) } = myVal f := i.M; f(7) // like i.M(7)
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句