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

Go 类型将自定义类型断言为基类型,go,types,type-conversion,type-assertion,Go,Types,Type Conversion,Type Assertion,是否可以将自定义类型断言为其基类型 例如,如果我有以下内容 type A []interface{} var x = map[string]interface{}{ "hello":"a", "world":A{"b","c"}, } y := x["world"] 然后,如果我试图通过y.([]接口{})键入assert,我会得到错误//接口{}是A,而不是[]接口{} 编辑:正如下面的答案所指出的,我可以通过y.(A)断言键入A。问题源于Mong

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

例如,如果我有以下内容

type A []interface{}

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

y := x["world"]
然后,如果我试图通过
y.([]接口{})
键入assert,我会得到错误
//接口{}是A,而不是[]接口{}

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

您不能将
y
变为
[]接口{}
,因为
y
的实际数据类型是
A
(即使
A
[]接口{}
的别名)

工作示例:

fmt.Println(y.(A))
但您可以使用将数据类型为
A
的变量转换为
[]接口{}
。例如:

w:=y.(A)
x:=[]接口{}(w)
//或
z:=[]接口{}(y(A))
当(对)一个具体类型时,类型只能断言存储在接口值中的相同类型,而不能断言其基类型。当然,当您拥有混凝土类型时,可以将其转换为基础类型

你说你想避免,你想避免引用具体类型

要做到这一点,你需要反思。获取值的描述符,并使用该方法“直接”转换为其基类型,跳过“实际”类型。这将成功,因为可以将值转换为其基类型的值

当然,
Value.Convert()
方法将生成类型为
reflect.Value
(而不是
[]接口{}
)的值,但是您可以使用该方法获得包装该值的
接口{}
值。现在您将拥有一个
接口{}
,它封装了一个具体的
[]接口{}
类型的值,您现在可以从中键入并断言一个
[]接口{}
类型的值

请参见此示例:

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

fmt.Printf("%T %v", z, z)
输出(在上尝试):


这里有很多样板文件,但这远不如简单的类型断言和转换有效。尽量避免这样做。

如果需要访问特定于动态类型的内容,例如结构字段或不属于接口的方法,则只需声明接口值的类型。如果您依赖于某个特定驱动程序的特定内容,那么显然,该代码将无法与其他驱动程序一起使用。那就别那么做。只依赖于与您想要支持的所有驱动程序一起工作的某个通用接口。
A
不是
接口{}
的一种。
[]interface {} [b c]