我发现值类型和引用类型之间的接口可满足性令人困惑。我仍然无法弄清楚它如何在golang中运行。考虑一下这个程序:
type Counter1 int
type Counter2 int
func (c Counter1) String() string {
}
func (c *Counter2) String() string {
}
func main() {
var c1 Counter1
var c2 Counter2
var i1 fmt.Stringer = &c1 // assignment 1
var i2 fmt.Stringer = c2 // assignment 2
}
但是作业1有效,但作业2没有。我预计它们都不起作用:类型Counter1满足fmt.Stringer但是类型* Counter1没有。所以& c1不应该分配给i1;类型Counter2不满足fmt.Stringer但是* Counter2类型,所以c2不应该分配给i2,实际上它不能。这个测试程序的结果对我来说没有意义。我认为它可能是某种语法糖,go编译器会自动在引用类型和值类型之间进行转换。但是下面的测试代码让我更加困惑:
type Test interface {
f()
g()
}
func (c Counter1) f() {
}
func (c *Counter1) g() {
}
func receiveTest(t Test) {
}
func main() {
......
var c3 Counter1
var p3 Test = &c3 // works
receiveTest(&c3) // works
receiveTest(c3) // doesn't work
}
类型* Counter1和类型Counter1都不满足接口Test。但是第一次和第二次分配仍然有效。这对我没有意义。
答案 0 :(得分:3)
在Go中,选择器表达式(
x.f
)表示值f
(或有时x
)的字段或方法*x
。
基本上,在Go中,如果方法上有指针接收器,则不必编写&object.method()
,但只需编写object.method()
https://play.golang.org/p/nh8X-vwdfr
https://play.golang.org/p/1uKwZw6E-J
因为接口在Go中是隐式的,只要对象本身不是指针,那么如果满足接口的方法具有指针接收器并不重要,它们仍将用于满足它
因此,在您的示例中,Counter1
结构可以同时调用f()
和g()
个方法,但*Counter1
只能有g()
调用它的方法。