【问题标题】:Golang how to do type assertion for unknown interface?Golang如何为未知接口做类型断言?
【发布时间】:2014-02-01 17:33:45
【问题描述】:

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

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

【问题讨论】:

    标签: go


    【解决方案1】:

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

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

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

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

    您所要求的是不可能的原因是编译器必须知道您要检查的类型,以便它可以编写我为上面提供的伪代码的检查。不知道t是什么,就无法知道s的静态类型应该是什么,也无法检查是否正确。

    【讨论】:

    • 谢谢,有道理。但是如何根据对象传递的类型创建一个具体实例呢?具体我的意思是不通过反射引用,尽管使用反射来获得它很好。
    • 你能做的最好的事情就是得到这样一个类型的接口值。像这样的东西:reflect.New(reflect.TypeOf(obj)).Interface().
    猜你喜欢
    • 1970-01-01
    • 2020-05-15
    • 2023-04-03
    • 2014-01-22
    • 2019-01-01
    • 2019-11-03
    • 1970-01-01
    • 1970-01-01
    • 2015-03-10
    相关资源
    最近更新 更多