进行类型强转,就可以通过打断点的方式来查看了 。
func TestErr(t *testing.T) { txn, err := startTx() fmt.Println(reflect.TypeOf(err), reflect.ValueOf(err)) if err != nil {log.Fatalf("err starting tx: %v", err) } p := (*iface)(unsafe.Pointer(&err)) fmt.Println(p.data) if err = txn.doUpdate(); err != nil {fmt.Println(reflect.TypeOf(err), reflect.ValueOf(err))p := (*iface)(unsafe.Pointer(&err))fmt.Println(p.data)log.Fatalf("err updating: %v", err) } if err = txn.commit(); err != nil {log.Fatalf("err committing: %v", err) } fmt.Println("success!")}
文章插图
补充说明一下 , 这里的
inter.typ.kind
表示的是变量的基本类型,其值对应 runtime
包下的枚举 。const ( kindBool = 1 + iota kindInt kindInt8 kindInt16 kindInt32 kindInt64 kindUint kindUint8 kindUint16 kindUint32 kindUint64 kindUintptr kindFloat32 kindFloat64 kindComplex64 kindComplex128 kindArray kindChan kindFunc kindInterface kindMap kindPtr kindSlice kindString kindStruct kindUnsafePointer kindDirectIface = 1 << 5 kindGCProg= 1 << 6 kindMask= (1 << 5) - 1)
比如上图中所示的 kind = 20
对应的类型就是 kindInterface
。总结
- 接口类型变量跟普通变量是有差异的,非空接口类型变量对应的底层结构是
iface
,空接口类型类型变量对应的底层结构是eface
。 iface
中有两个跟类型相关的字段,一个表示的是接口的类型i
nter,一个表示的是变量实际类型_type
。- 只有当接口变量的
itab._type
与 data 都为nil
时,也就是实际类型和值都未被赋值前 , 才真正等于nil
。
推荐阅读
- 黑鲨4pro为什么不建议买_黑鲨4pro骂声一片原因
- 电脑?号怎么打出来(电脑为什么打不出来字)
- 羊了个羊为什么进不去
- 羊了个羊通关率为什么会不到0.1%
- McAfee如何卸载干净(mcafee为什么卸载不了)
- 语音发出后录音还在继续_语音发出之后为什么还在录音
- 不吹不黑,锤子手机真的好用吗为什么(现在的锤子手机怎么样)
- 红心大战到底怎么玩儿?为什么我总是多分(红心大战得分越低越好吗)
- golang中的nil接收器
- 为什么说:保险柜没有钥匙时,只用笔帽就可以打开怎么做到的