为什么第一个示例失败,但第二个成功?做这种断言的正确方法是什么?示例 1 https://play.golang.org/p/4LRGQLdGPB// example 1type Packet map[string]interface{}func get(pack interface{}) { if packet, ok := pack.(Packet); !ok { fmt.Printf("error: %#v, %#v\n", pack, packet) }}func main() { pack := make(map[string]interface{}) pack["qwe"] = 123 get(pack)}// error: map[string]interface {}{"qwe":123}, main.Packet(nil)示例 2 https://play.golang.org/p/Pd9jvvNrq5// example 2type Packet map[string]interface{}func get(pack interface{}) { var p Packet if packet, ok := pack.(map[string]interface{}); !ok { fmt.Printf("%#v, %#v\n", pack, packet) } else { p = packet } fmt.Printf("%#v\n", p)}func main() { pack := make(map[string]interface{}) pack["qwe"] = 123 get(pack)}// main.Packet{"qwe":123}
2 回答
慕仙森
TA贡献1827条经验 获得超7个赞
问题是你没有传递 a Packet
,你传递的map[string]interface{}
是 a ,就 Go 而言,这是一种完全不同的类型。
如果您使用pack := make(Packet)
or pack := Packet{}
,它将按预期工作。
至尊宝的传说
TA贡献1789条经验 获得超10个赞
到目前为止的答案和评论是误解,混淆,或者至少在类型断言和类型转换之间的区别中刷了很多细节。
语法thing.(AType)
是类型断言。它将在运行时进行评估。何时成功(即ok == true
)的标准可以归结为两种情况:
thing
从字面上看是 typeAType
。不是像您的Packet
.AType
是接口,thing
满足接口。
在所有其他情况下,ok
将是false
(或者如果您使用单值版本foo := bar.(Baz)
,foo
将是适当的零值)。
语法AType(thing)
是类型转换。它将在编译时进行评估。类型转换要求内存中的结构AType
和任何类型thing
都是相同的。
因此,在您的示例中,类型断言packet, ok := pack.(Packet)
导致ok == false
因为Packet
是非接口类型,并且packet
不是字面上的那种类型,而是类型map[string]interface
。
但是,您可以进行类型转换Packet(pack)
,因为类型Packet
和变量pack
具有相同的底层内存结构,map[string]interface{}
- 2 回答
- 0 关注
- 180 浏览
添加回答
举报
0/150
提交
取消