为了账号安全,请及时绑定邮箱和手机立即绑定

接口不能调用self方法

接口不能调用self方法

Go
Smart猫小萌 2023-04-24 15:37:37
我定义了两个函数。当我向它传递一个指针时,我无法获得定义的方法。为什么是这样?type Visitor interface {    work()}func test(v *Visitor)  {    v.work() // error}func test1(v Visitor)  {    v.work() // ok}错误:v.work 未定义(类型 *Visitor 是指向接口的指针,而不是接口)谁知道为什么
查看完整描述

2 回答

?
慕尼黑5688855

TA贡献1848条经验 获得超2个赞

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进一步的规则适用于包含嵌入式字段的结构,如结构类型部分所述。任何其他类型都有一个空方法集。在一个方法集中,每个方法必须有一个唯一的非空白 方法名称。

不同之处在于您对接口类型进行了相同的尝试,但这是行不通的。它适用于具体(非接口)类型。教训是永远不要使用指向接口的指针,除非你能解释为什么需要它(很少需要)。


查看完整回答
反对 回复 2023-04-24
?
慕工程0101907

TA贡献1887条经验 获得超5个赞

正如错误明确指出的那样:

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

这是因为 work() 函数是在指向接收器的指针上调用但在值上定义的。

type Visitor interface {
    work()
}

但是在第二种情况下你正在传递指针类型的接收器,你会得到一个错误。

在 Golang 规范中,方法集定义为:

一个类型可能有一个与之关联的方法集。接口类型的方法集就是它的接口。任何其他类型T的方法集由所有声明为接收者类型T的方法组成。对应指针类型*T的方法集是所有声明为接收者*T或T的方法的集合(即还包含方法T 组)。进一步的规则适用于包含嵌入字段的结构,如结构类型部分所述。任何其他类型都有一个空方法集。在一个方法集中,每个方法必须有一个唯一的非空方法名。

您可以采用的一种方法是使用可以在其上调用方法 work() 的结构来实现接口。

package main


import "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)

}


查看完整回答
反对 回复 2023-04-24
  • 2 回答
  • 0 关注
  • 119 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信