我遇到问题去接口。
这是我的main.go文件;
package main
import (
"fmt"
"bitbucket.org/xyz/trash/a"
)
// Second -
type Second interface {
Area() float64
}
// Area -
func Area() float64 {
return 2
}
func main() {
r := new(a.Rect)
n := new(Second)
r.F = *n
fmt.Println(r.Area())
}
我的另一个包,a.go;
package a
// First -
type First interface {
Area() float64
}
// Rect -
type Rect struct {
F First
}
// Area -
func (r Rect) Area() float64 {
return 1
}
我期待这一行
fmt.Println(r.Area())
打印“2”,而不是“1”。我错过了什么?
感谢您的帮助。
答案 0 :(得分:2)
对接口是什么有误解。在go中,如果类型实现为接口定义的函数,则类型实现接口。因此,在您的代码中,接口text-align:justify;
和a.First
等效。类型实现它们或根本不实现。
因此,main.Second
类型既是Rect
又是a.First
。 Rect中的字段F表示它包含另一个实现First(或第二个因为它们相同)的类型。
当您致电main.Second
时,请执行功能r.Area()
。使用行func (r Rect) Area() uint64
,您可以将第二个参数分配给第一个(它们是等效的,没问题)。但是,如果你试图调用r.F = *n
,它会引起恐慌,因为F不是一个实现First的类型,它是 First。
因此,您应该创建另一个实现First的类型然后将其分配给r。然后你可以拨打r.F.Area()
。
答案 1 :(得分:2)
首先,再次查看您的代码。如上所述,a.Rect.Area()
返回1.它始终返回1.设置您喜欢的所有属性。它返回1.咬牙切齿,诅咒众神。它返回1.因为它是一个返回1的函数。这就是它的作用。
像这样写:
// Area -
func (r Rect) Area() float64 {
return r.F.Area()
}
......你会因为另外一个问题而感到恐慌。
main.go中的 Area()
没有接收器。它与接口无关。这只是一个功能。没有对象。没有任何实施。没有多态性。没什么。
您已将n
声明为指向接口的指针,而不是接口的实现。这是零。如果你试图取消引用它,那么整个世界将会陷入虚空之中。
如果您希望能够拨打n.Area()
,请将Second
设为具体类型。
(在main.go中)
// Second -
type Second struct {}
// Area -
func (s Second) Area() float64 {
return 2
}
你看到了区别吗?第二个现在是<{1}} 实现接口struct
,因为它是适当的a.First
方法的接收者。因此,您将获得预期的行为。