为了账号安全,请及时绑定邮箱和手机立即绑定

类型断言和接口

类型断言和接口

Go
倚天杖 2022-01-10 14:29:58
为什么第一个示例失败,但第二个成功?做这种断言的正确方法是什么?示例 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{},它将按预期工作。


查看完整回答
反对 回复 2022-01-10
?
至尊宝的传说

TA贡献1789条经验 获得超10个赞

到目前为止的答案和评论是误解,混淆,或者至少在类型断言类型转换之间的区别中刷了很多细节。

语法thing.(AType)是类型断言。它将在运行时进行评估。何时成功(即ok == true)的标准可以归结为两种情况:

  1. thing从字面上看是 type AType。不是像您的Packet.

  2. 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{}


查看完整回答
反对 回复 2022-01-10
  • 2 回答
  • 0 关注
  • 180 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信