GoLang上的接口函数调用

GoLang上的接口函数调用,go,interface,Go,Interface,我有一个问题去接口 这是我的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(S

我有一个问题去接口

这是我的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(右面积())

打印“2”,而不是“1”。我错过了什么


感谢您的帮助。

对接口的定义存在误解。在go中,如果类型实现了为接口定义的函数,那么它将实现接口。因此,在您的代码中,接口
a.First
main.Second
是等价的。一个类型同时实现它们或根本不实现它们

因此,类型
Rect
既是
a.First
又是
main.Second
。Rect中的字段F表示它包含另一个实现第一个(或第二个,因为它们是相同的)的类型

调用
r.Area()
时,go执行函数
func(r Rect)Area()uint64
。使用行
r.F=*n
,将接口从第二个分配给第一个(它们是等效的,没有问题)。但是,如果您尝试调用
r.F.Area()
它将死机,因为F不是一个首先实现的类型,而是第一个实现的类型


因此,您应该创建另一个类型,该类型首先实现,然后将其分配给r。然后您可以调用
r.F.Area()

对接口是什么存在误解。在go中,如果类型实现了为接口定义的函数,那么它将实现接口。因此,在您的代码中,接口
a.First
main.Second
是等价的。一个类型同时实现它们或根本不实现它们

因此,类型
Rect
既是
a.First
又是
main.Second
。Rect中的字段F表示它包含另一个实现第一个(或第二个,因为它们是相同的)的类型

调用
r.Area()
时,go执行函数
func(r Rect)Area()uint64
。使用行
r.F=*n
,将接口从第二个分配给第一个(它们是等效的,没有问题)。但是,如果您尝试调用
r.F.Area()
它将死机,因为F不是一个首先实现的类型,而是第一个实现的类型


因此,您应该创建另一个类型,该类型首先实现,然后将其分配给r。然后您可以调用
r.F.Area()

首先,再次查看您的代码。如前所述,
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中)


你看到区别了吗?第二个是实现接口的
a的
struct
。因此,您将获得预期的行为。

首先,再次查看您的代码。如前所述,
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中)


你看到区别了吗?第二个是实现接口的
a的
struct
。因此,您将获得预期的行为。

嘿。谢谢实际上,我试图实现的是,使“r”具有我的新接口(n)。未调用全局函数。您已经实现了Rect的接口,无法更改它。我把我的答案解释了一点。谢谢实际上,我试图实现的是,使“r”具有我的新接口(n)。未调用全局函数。您已经实现了Rect的接口,无法更改它。我详细阐述了我的回答。