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

时间:2014-02-01 08:22:04

标签: 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函数中你永远不会知道实际传递的对象类型,那么如何完成类型断言呢?

1 个答案:

答案 0 :(得分:11)

你做不到。类型断言允许您利用语言为您提供的静态类型检查,即使您有一个非静态检查类型的接口。它基本上是这样的:

您有一些静态类型变量s,其类型为t。如果您尝试使用s,就好像它是一个不同的类型,编译器会通过拒绝编译来强制保证t始终具有类型s,因为这会破坏保证。 / p>

您还有一些界面变量ii的类型在编译时是未知的,因此编译器无法保证将i分配给s不会破坏s具有的保证输入t。但是,可以做的是类型断言。类型断言一边说这个问题,说:“好吧,我会在运行时检查,如果类型匹配,我只会进行分配。”编译器没问题,因为它知道只有在类型匹配时才会发生赋值,这意味着它仍然可以保证s具有类型t。所以基本上在运行时发生的事情是:

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

你要求的是不可能的原因是编译器已经知道你正在检查什么类型,以便它可以编写我给上面给出伪代码的检查。在不知道t是什么的情况下,无法知道s的静态类型应该是什么,也无法检查它是否正确。