GO语言语法糖: 直接调用 与 实现接口调用

如下只考虑编译通过, 不考虑是否真实修改

1. 直接调用方法时的规则:

值类型可以调用值接收者方法
值类型可以调用指针接收者方法
指针类型可以调用值接收者方法
指针类型可以调用指针接收者方法

package main

type IDraw interface {
    getName() string
    setName(string)
}
type Rect struct {
    name string
}
func (p Rect) getName() string {
    return p.name
}
func (p *Rect) setName(name string) {
    p.name = name
}
func main() {
    var rect Rect = Rect{name: "rect"}
    rect.getName()
    rect.setName("rect")
    var prect *Rect = &Rect{name: "rect"}
    prect.getName()
    prect.setName("rect")
}

2. 实现接口时的规则:

如果接口所有方法都是值接收者实现的,那么值类型和指针类型都可以实现该接口

package main
type IDraw interface {
    getName() string
    setName(string)
}
type Rect struct {
    name string
}
func (p Rect) getName() string {
    return p.name
}
func (p Rect) setName(name string) {
    p.name = name
}
func main() {
    var draw IDraw = Rect{}
    draw.getName()
    draw.setName("test")
    var pdraw IDraw = &Rect{}
    pdraw.getName()
    pdraw.setName("test")
}

如果接口任何一个方法是指针接收者实现的,那么只有指针类型能实现该接口

package main
type IDraw interface {
    getName() string
    setName(string)
}
type Rect struct {
    name string
}
func (p Rect) getName() string {
    return p.name
}
func (p *Rect) setName(name string) {
    p.name = name
}
func main() {
    var draw IDraw = Rect{} //报错, cannot use Rect{} (value of type Rect) as IDraw value in variable declaration: Rect does not implement IDraw (method setName has pointer receiver)compilerInvalidIfaceAssign
    draw.getName()
    draw.setName("test")
    var pdraw IDraw = &Rect{}
    pdraw.getName()
    pdraw.setName("test")

}

3. 注意

如果接口任何一个方法是指针接收者实现的,那么只有指针类型能实现该接口

type Integer int
func (i *Integer) AddV(b Integer) Integer {
    return *i + b
}
func (a Integer) Add(b Integer) Integer {
    return Integer(a + b)
}
func main() {
    var a Integer = 1
    var b Integer = 2
    var i interface{} = &a
    sum := i.(*Integer).Add(b)
    sumV := i.(*Integer).AddV(b)
    fmt.Println(sum)
    fmt.Println(sumV)
}

为什么支持值类型实现该接口?

关键点在于:
  1. 这里并没有定义显式的接口类型,而是使用了空接口interface{}
  2. 空接口不包含任何方法要求,所以任何类型都实现了空接口
  3. 当你使用i.(*Integer)进行类型断言时,是在把接口值转换回具体类型
  4. 类型断言后,就可以直接调用该类型的任何方法,不管是值接收者还是指针接收者的方法
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容