将自定义类型类型断言为基本类型

Type assert custom type to base type

是否可以将自定义类型断言为其基类型?

例如,如果我有以下

type A []interface{}

var x = map[string]interface{}{
        "hello":"a",
        "world":A{"b","c"},
    }

y := x["world"]

然后,如果我尝试通过 y.([]interface{}) 键入断言,我会得到错误 //interface {} is A, not []interface {}

编辑:正如下面的回答所指出的,我可以断言通过 y.(A) 键入 A。问题源于 Mongo 驱动程序给出的 x。一些驱动程序实现了自己的类型,例如,官方 mongo 驱动程序为 []interface 类型实现了 bson.A 类型。如果我切换驱动程序,那么我的类型断言需要更改以匹配它们的自定义类型,这是我想避免的事情。

你不能type assert变量y[]interface{}因为y的实际数据类型是A(即使A[]interface{}).

的别名

工作示例:

fmt.Println(y.(A))

但是您可以使用conversion将数据类型为A的变量转换为[]interface{}。示例:

w := y.(A)
x := []interface{}(w)

// or 

z := []interface{}(y.(A))

type asserting (to) a concrete type, you can only type assert the same type that is stored in the interface value, not its base type. Of course when you have the concrete type, you can convert 表示为它的基类型时。

你说你想避免这种情况,你想避免引用具体类型。

为此,您需要反思。获取 reflect.Value descriptor of the value, and use the Value.Convert() 方法以 "directly" 转换为其基类型,跳过 "actual" 类型。这会成功,因为值可以转换为其基类型的值。

当然,Value.Convert() 方法会产生一个 reflect.Value 类型的值(而不是 []interface{}),但是您可以使用 Value.Interface()。您现在将拥有一个 interface{},它包装了一个 []interface{} 类型的具体值,您现在可以从中键入 assert 一个 []interface{}.

类型的值

看这个例子:

z := reflect.ValueOf(y).Convert(reflect.TypeOf([]interface{}{})).
    Interface().([]interface{})

fmt.Printf("%T %v", z, z)

输出(在 Go Playground 上尝试):

[]interface {} [b c]

这里有很多样板文件,这不会像简单的 type-assertion 和转换那样有效。尽量避免这样做。