为什么第一个例子失败了,但第二个例子顺利?
这种断言的正确方法是什么?
示例1 https://play.golang.org/p/4LRGQLdGPB
// example 1
type 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 2
type 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}
答案 0 :(得分:1)
问题是你没有传递Packet
,你传递的是map[string]interface{}
,就Go而言,这是一种完全不同的类型。
如果您使用pack := make(Packet)
或pack := Packet{}
,它将按预期工作。
答案 1 :(得分:0)
到目前为止,答案和评论都是误解,混淆,或至少在type assertion和type conversion之间的细微差别。
语法thing.(AType)
是一种类型断言。它将在运行时评估。何时成功(即ok == true
)的标准可归结为两种情况:
thing
字面上是AType
类型。不是像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{}