小编典典

Golang如何为未知接口进行类型断言?

go

我知道我可以通过反射来获取对象的值,然后使用类型断言使用以下方法来获取实际对象:

obj := new(User)
out := reflect.ValueOf(obj).Elem().Interface().(User)
fmt.Println(out == *obj) // true

但是,如果我不知道对象的类型是User,该怎么办呢?说它在像这样的函数中:

func Foo(obj interface{}) bool {
    // out := reflect.ValueOf(obj).Elem().Interface().( ... )
    return out == *obj
}

func main() {
    obj := new(User)
    fmt.Println(Foo(obj))
}

Foo函数内部,您将永远不知道实际上将传递哪种类型的对象,那么如何完成类型声明?


阅读 307

收藏
2020-07-02

共1个答案

小编典典

你不能 类型断言使您可以利用语言为您提供的静态类型检查,即使您有一个接口,其类型不是静态检查的。基本上它是这样的:

你有一些静态类型的变量s,它有型t。如果您试图像其他类型一样使用,则编译器通过拒绝编译来强制s始终具有类型的保证,因为这会破坏保证。t``s

您还可以使用一些接口变量ii的类型在编译时未知,因此编译器无法保证分配is不会破坏s具有type 的保证t。但是,您 可以
做的是类型声明。类型断言通过说:“好吧,我会在运行时检查,并且仅在类型匹配时才进行赋值”,从而避免了该问题。编译器可以这样做,因为它知道只有在类型匹配时才会发生分配,这意味着它仍然可以保证s具有type
t。因此,基本上在运行时发生的是:

if (i has type t) {
    s = i
} else {
    s = t{} // Zero value of t
}

您无法要求的原因是,编译器 必须
知道您要针对哪种类型进行检查,以便编译器可以编写我上面给出的伪代码的检查。不知道是什么t,就没有办法知道s应该是什么静态类型,也没有办法检查它是否正确。

2020-07-02