2.执行机制
最后更新于:2022-04-02 04:44:39
Golang 接口执行机制 :接口对象由接口表 (interface table) 指针和数据指针组成。
接口表存储元数据信息,包括接口类型、动态类型,以及实现接口的方法指针。无论是反射还是通过接口调用方法,都会用到这些信息。
数据指针持有的是目标对象的只读复制品,复制完整对象或指针。
~~~
package main
import "fmt"
type User struct {
id int
name string
}
func main() {
u := User{1, "Tom"}
var i interface{} = u
u.id = 2
u.name = "Jack"
fmt.Printf("%v\n", u)
fmt.Printf("%v\n", i.(User))
}
~~~
输出结果:
~~~
{2 Jack}
{1 Tom}
~~~
接口转型返回临时对象,只有使用指针才能修改其状态。
~~~
package main
import "fmt"
type User struct {
id int
name string
}
func main() {
u := User{1, "Tom"}
var vi, pi interface{} = u, &u
// vi.(User).name = "Jack" // Error: cannot assign to vi.(User).name
pi.(*User).name = "Jack"
fmt.Printf("%v\n", vi.(User))
fmt.Printf("%v\n", pi.(*User))
}
~~~
输出结果:
~~~
{1 Tom}
&{1 Jack}
~~~
只有 tab 和 data 都为 nil 时,接口才等于 nil。
~~~
package main
import (
"fmt"
"reflect"
"unsafe"
)
var a interface{} = nil // tab = nil, data = nil
var b interface{} = (*int)(nil) // tab 包含 *int 类型信息, data = nil
type iface struct {
itab, data uintptr
}
func main() {
ia := *(*iface)(unsafe.Pointer(&a))
ib := *(*iface)(unsafe.Pointer(&b))
fmt.Println(a == nil, ia)
fmt.Println(b == nil, ib, reflect.ValueOf(b).IsNil())
}
~~~
输出结果:
~~~
true {0 0}
false {17424320 0} true
~~~
';