乐趣区

关于go:golang中的接口实现调用修改值接收者指针接收者

比方有以下阐明:

阐明 备注
接口 比方一个 coder 的 interface,有 code 和 debug 办法
办法接收者(实现接口) 可能有多个,比方 phper,golanger,可能是值接管(对象),也可能是指针接管(对象指针)
调用者为:接口 就是接口 coder 调用
调用者为:办法接收者 比方 phper,golanger,调用者可能是值调用(对象),或者指针调用(对象指针)

对于调用

调用者为 办法接收者

无论办法接收者(实现接口)是值接管(对象),还是是指针接管(对象指针),都能够用调用者间接调用办法。此时调用者不受是值还是指针的限度。

换句话说:无论接收者是值类型还是指针类型,都能够通过值类型或者指针类型调用。起因是这里有寻址及解援用的隐形操作。

调用者为 接口

先说调用者为接口的意思是:

type Coder interface {code()
    debug()}

func Work(c Coder){c.code()
    c.debug()}
type Golang struct {

}
type PHP struct {

}

func (g *Golang) code(){fmt.Println("golang code")
}
func (g *Golang) debug(){fmt.Println("golang debug")
}

func (g *PHP) code(){fmt.Println("php code")
}
func (g PHP) debug(){fmt.Println("php debug")
}
// 这里了解为调用者为接口,var c Coder=&PHP{}
c.debug()
c.code()

这里次要波及到接口转换,及须要把 coder 转为 phper 或者 golanger
论断:实现接收者是值类型的接口办法时,能够失常地用值或指针进行接口转换,
但实现接收者是指针类型的办法时,接口转换只能应用指针,不能应用值类型。

起因:
通过值能够找到值对应惟一的指针(无论是应用值还是应用指针,办法集都是一样的)。

然而,实现接收者是指针类型的办法时,接口转换只能应用指针,不能应用值类型。这是因为指针办法冀望的是一个能够被取地址的对象,而通过值类型进行接口转换时,你可能会传递一个无奈取地址的长期对象,这会导致无奈调用指针办法。

对于批改

如果办法的接收者是值类型,无论调用者是对象还是对象指针,批改的都是其正本,调用者自身不会更改。
如果办法接收者是指针类型,批改的就是调用者自身。

当你不须要批改状态且要防止并发问题时,值类型接收者是个不错的抉择。
当你须要批改状态、须要在并发环境下操作或者须要缩小值拷贝时,指针类型接收者更适合。

抉择接收者是值类型还是指针类型取决于多种因素,包含可修改性、并发操作和内存开销。

接收者是值类型的场景:

  1. 不须要批改接收者的状态:

    如果办法不须要批改接收者的状态,而只是基于其属性进行操作,那么能够应用值类型接收者。这样能够防止意外的副作用。

  1. 防止并发问题:

    值类型接收者是线程平安的,因为它们在办法外部只操作接收者的正本,不会影响原始数据的状态。这在并发环境中往往更容易治理。

接收者是指针类型的状况:

  1. 须要批改接收者的状态:

    如果办法须要批改接收者的状态,那么你必须应用指针类型接收者。这样能够在办法外部批改原始数据,而不仅仅是操作正本。

  2. 防止值拷贝带来的内存开销:

    对于大型的构造体或对象,应用指针类型接收者能够防止在办法调用时进行值的拷贝,缩小内存和性能开销。

退出移动版