接口不能调用自我方法

I have defined two functions. When I pass a pointer to it, I can't get the defined method. Why is this?

type Visitor interface {
    work()
}

func test(v *Visitor)  {
    v.work() // error
}


func test1(v Visitor)  {
    v.work() // ok
}

Error:

v.work undefined (type *Visitor is pointer to interface, not interface)

anyone know why, ths

func test(v *Visitor)  {
    v.work() // error
}

v.work() ought to be a method call. But v is of type *Visitor, a pointer to interface. A pointer to interface has 0 methods, it does not implement anything (except the empty interface interface{}).

When using a non-pointer, the value v (or rather its type) has a method work(), so you can call that:

func test(v Visitor)  {
    v.work() // ok
}

Here v.work() works, because the v is of type Visitor which is an interface, and it contains the method work().

What may be confusing is that if you add method to a (non-pointer, non-interface) concrete type, the respective pointer type will also have that method, and you can call that. This is in Spec: Method sets:

A type may have a method set associated with it. The method set of an interface type is its interface. The method set of any other type T consists of all methods declared with receiver type T. The method set of the corresponding pointer type *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T). Further rules apply to structs containing embedded fields, as described in the section on struct types. Any other type has an empty method set. In a method set, each method must have a unique non-blank method name.

The difference is that you tried the same with interface type, which won't work. It works with concrete (non-interface) types. Lesson is to never use pointer to interface unless you can reason why it is needed (it is rarely needed).

As the error clearly states:

v.work undefined (type *Visitor is pointer to interface, not interface)

This is because the work() function is called on pointer to the receiver but defined on value.

type Visitor interface {
    work()
}

But you are passing pointer type receiver in second case in which you are getting an error.

In Golang spec Method sets are defined as:

A type may have a method set associated with it. The method set of an interface type is its interface. The method set of any other type T consists of all methods declared with receiver type T. The method set of the corresponding pointer type *T is the set of all methods declared with receiver *T or T (that is, it also contains the method set of T). Further rules apply to structs containing embedded fields, as described in the section on struct types. Any other type has an empty method set. In a method set, each method must have a unique non-blank method name.

One approach you can do is Implement the interface by using the struct on which you can call the method 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)
}

Working Code on Go playground