猿问

接口不能调用self方法

我定义了两个函数。当我向它传递一个指针时,我无法获得定义的方法。为什么是这样?


type Visitor interface {

    work()

}


func test(v *Visitor)  {

    v.work() // error

}



func test1(v Visitor)  {

    v.work() // ok

}

错误:


v.work 未定义(类型 *Visitor 是指向接口的指针,而不是接口)


谁知道为什么


Smart猫小萌
浏览 120回答 2
2回答

慕尼黑5688855

func test(v *Visitor)  {     v.work() // error     }v.work()应该是一个方法调用。但是v是 type *Visitor,一个指向接口的指针。指向接口的指针有 0 个方法,它不实现任何东西(空接口除外interface{})。使用非指针时,值v(或更确切地说它的类型)有一个 method work(),因此您可以调用它:func test(v Visitor)  {     v.work() // ok     }这里v.work()有效,因为vis 是一个接口类型Visitor,它包含方法work()。可能令人困惑的是,如果您将方法添加到(非指针,非接口)具体类型,则相应的指针类型也将具有该方法,您可以调用它。这是在规范中:方法集:一个类型可能有一个与之关联的方法集。接口类型的方法集就是它的接口。任何其他类型的方法集T由所有用接收者类型声明的方法T组成。对应指针类型的方法集是所有用receiver or声明的方法的集合(即也包含了 的方法集)。 *T*TTT进一步的规则适用于包含嵌入式字段的结构,如结构类型部分所述。任何其他类型都有一个空方法集。在一个方法集中,每个方法必须有一个唯一的非空白 方法名称。不同之处在于您对接口类型进行了相同的尝试,但这是行不通的。它适用于具体(非接口)类型。教训是永远不要使用指向接口的指针,除非你能解释为什么需要它(很少需要)。

慕工程0101907

正如错误明确指出的那样:v.work 未定义(类型 *Visitor 是指向接口的指针,而不是接口)这是因为 work() 函数是在指向接收器的指针上调用但在值上定义的。type Visitor interface {     work() }但是在第二种情况下你正在传递指针类型的接收器,你会得到一个错误。在 Golang 规范中,方法集定义为:一个类型可能有一个与之关联的方法集。接口类型的方法集就是它的接口。任何其他类型T的方法集由所有声明为接收者类型T的方法组成。对应指针类型*T的方法集是所有声明为接收者*T或T的方法的集合(即还包含方法T 组)。进一步的规则适用于包含嵌入字段的结构,如结构类型部分所述。任何其他类型都有一个空方法集。在一个方法集中,每个方法必须有一个唯一的非空方法名。您可以采用的一种方法是使用可以在其上调用方法 work() 的结构来实现接口。package mainimport "fmt"type Visitor struct{}type Visit interface {    work()}func test(v Visit)  {    v.work() // error    fmt.Printf("%+v", v)}func (v *Visitor) work(){}func main(){       v := Visitor{}       test(&v)}
随时随地看视频慕课网APP

相关分类

Go
我要回答