annidy / notes

0 stars 0 forks source link

value vs pointer receiver #302

Open annidy opened 1 month ago

annidy commented 1 month ago
  1. 结构体不允许同时同名方法
    
    type Foo struct {
    }

func (f *Foo) Foo() { fmt.Println("ptr foo") }

/ func (f Foo) Foo() { fmt.Println("value foo") } /

func (f Foo) VFoo() { fmt.Println("value foo") }

不能定义两个Foo方法

2. 调用结构体对象方法,编译器会自动转换
```go
foo := &Foo{}
foo.VFoo() // 编译器自动转换  (*pfoo).VFoo()

foo = Foo{}
foo.Foo() // 编译器自动转换 (&vfoo).Foo()

编译器知道对象foo的类型

  1. interface为了安全,只支持指针转值
    
    type Fooer interface {
    Foo()
    }

var _ Fooer = Foo{}



报错
> cannot use Foo{} (value of type Foo) as Fooer value in variable declaration: Foo does not implement Fooer (method Foo has pointer receiver)compiler[InvalidIfaceAssign](https://pkg.go.dev/golang.org/x/tools/internal/typesinternal#InvalidIfaceAssign)

Fooer没有什么receiver的类型,但是在创建实例时,会根据右值类型检查receiver。如果是对象,会检查 `func (p Foo) Foo()`有没有。
由于指针reciver可能修改内容,有副作用,而interface具体指向的实例又不确定。如果两个struct实现了不同receiver接口,可能会对调用者产生疑惑,所以要求更严格了