Golang 接口 & 指针
如 http.Handler 接口,有个困惑,为什么 第一个参数是value类型,第二个参数是指针类型呢?
<pre><code>type Handler interface { ServeHTTP(ResponseWriter, *Request) } </code></pre>Go里一切传递,都是传值,即便是指针。其实指针是一种特殊的类型包含了地址的值。
更进一步的发现,ResponseWriter 是接口类型。
<pre><code>type ResponseWriter interface { Header() Header Write([]byte) (int, error) WriteHeader(int) } </code></pre>interface 在运行时,会保存一个实现接口的对象,结构体里有两行,一个指向类型,另一个指向它关联的数据。
如果没有任何的数据绑定在接口上,Go可以指示接口实现,并提供编译时候的类型检查。
<pre><code>//(1) The interface type Mutable interface { mutate(newValue string) error } //(2) Struct type Data struct { name string } //(3) Implements the interface with a pointer receiver func (d *Data) mutate(newValue string) error { d.name = newValue return nil } //(4) Function that accepts the interface func mutator(mute Mutable) error { return mute.mutate("mutate") } func main() { d := Data{name: "fresh"} fmt.Println(d.name) //fresh //(5) pass as a pointer mutator(&d) fmt.Println(d.name) //mutate } </code></pre>在第三步,Data 实现了指针,可以改变内部的值
在第四步,函数 mutator 接受一个参数,来执行真正的改变操作。注意这里的参数是一个值,而不是指针。
第五步,我们传递了一个指针进去。貌似它违反了通常的golang 类型检查 type-check。例如,传递正常的类型会失败,但是传递接口是可以成功的。
例如下面的,就会编译失败
<pre><code>func thisWontWork(s string) { ... } v := "kirk" thisWontWork(&v) //compilation error </code></pre>参数的类型检查,确保参数 interface 和 结构体的 receiver 一致。
<pre><code> --------------------------------------------- | method receiver | parameter | | ------------------------------------------| | pointer | pointer | |-------------------------------------------| | value | value | | | pointer (dereferenced) | --------------------------------------------- </code></pre>让测一下上述的假设,通过改变 receiver 为一个 值类型,并传参为值。
<pre><code>//(1) Implements the interface with a value receiver func (d Data) mutate(newValue string) error { ... //(2) mutator function is UNCHANGED func mutator(mute Mutable) error { //(3) pass as value mutator(d) fmt.Println(d.name) //fresh </code></pre>你仍然可以看到,这个结构体,同样符合 mutator 函数的要求。但是该函数可能不太符合我们要求了,因为原始的值没有改变。
以下会编译错误:
<pre><code>//(1) Implements the interface with a pointer receiver func (d *Data) mutate(newValue string) error { //(2) Function is UNCHANGED func mutator(mute Mutable) error { //(3) Pass as value. Results in compilation error. mutator(d) </code></pre>interface 的实现者,可以有不同的类型的receivers
<pre><code>//(1) Define another struct that implements the interface type AnotherData struct {...} //(2) Implements as a value receiver. func (ad AnotherData) mutate(newValue string) error {...} //(3) Function is UNCHANGED func mutator(mute Mutable) error {...} //(4) Pass as a value. anotherData := AnotherData{name: "afresh"} fmt.Println(anotherData.name) //afresh mutator(anotherData) fmt.Println(anotherData.name) //afresh </code></pre>回到最初我们讨论的 Handler, 这里的response 结构体实现了 ResponseWriter 接口,同样带着 指针类型的receivers
【这里要解释 receiver和函数的区别】
Http Server 生成了一个 返回结构体,然后作为一个指针传递给handlers,这样可以使得 handlers 写值进入response 对象。
所以通常看来,即便 interface 可以被传值,更多的时候,它被作为指针来传递。
总结:
<ol><li>接口的实现方式决定了要传递的参数类型</li><li>值和指针receivers都是允许的,相同的接口,可以有不同的实现。</li><li>有人说 receivers 应该总是指针类型的,我会反驳,语言应该提供一个强制机制。</li></ol> 到此这篇关于“Golang 接口 & 指针”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!您可能感兴趣的文章:
Go结构体继承指针和非指针区别(转换接口)
Golang-对象方法和实现接口时,方法接受者是指针还是对象的区别
golang传递接口类型参数时,什么时候用指针
GO接口赋值与方法接收者问题
Golang 接口 & 指针
golang 接口 参数
GoLang学习笔记(三十四)接口及空接口
go语言接口断言的使用
golang积累-接口指针与结构体指针
Go学习笔记:接口实现与指针