简体   繁体   English

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

[英]Golang how to do type assertion for unknown interface?

I understand that I can get an object's value by reflection and then use type assertion to get back the actual object using: 我知道我可以通过反射得到一个对象的值,然后使用类型断言来获取实际对象:

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

But what if I don't know that the object's type is User , how can I do type assertion? 但是如果我不知道对象的类型是User ,我怎么能键入断言呢? Say it was inside a function like: 说它在一个函数内部:

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

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

Inside the Foo function you'll never know what type of object will actually be passed and so how do you complete the type assertion? Foo函数内部,您永远不会知道实际传递的对象类型,那么如何完成类型断言呢?

You can't. 你不能。 Type assertions allow you to take advantage of the static type checking that the language gives you even if you have an interface, whose type isn't statically checked. 类型断言允许您利用语言为您提供的静态类型检查,即使您有一个非静态检查类型的接口。 It basically works something like this: 它基本上是这样的:

You have some statically typed variable s , which has type t . 你有一些静态类型的变量s ,其类型为t The compiler enforces the guarantee that s always has type t by refusing to compile if you ever try to use s as if it were a different type, since that would break the guarantee. 如果您尝试使用s ,就好像它是一个不同的类型,编译器通过拒绝编译来强制执行s始终具有类型t的保证,因为这会破坏保证。

You also have some interface variable, i . 你也有一些接口变量, i i 's type is not known at compile-time, so there's no way the compiler can guarantee that assigning i to s wouldn't break the guarantee that s had type t . i的类型在编译时是不可知的,因此编译器无法保证将i分配给s不会破坏s类型为t的保证。 However, what you can do is a type assertion. 但是,您可以做的是类型断言。 A type assertion side-steps this problem by saying, "well, I'll check at run-time, and I'll only do the assignment if the types match up." 类型断言一边说这个问题,说:“好吧,我会在运行时检查,如果类型匹配,我只会进行分配。” The compiler is OK with this because it knows that the assignment will only happen if the types match up, which means that it can still guarantee that s has type t . 编译器可以正常使用它,因为它知道只有在类型匹配时才会发生赋值,这意味着它仍然可以保证s类型为t So basically what's happening at runtime is: 所以基本上在运行时发生的事情是:

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

The reason that what you're asking for is impossible is that the compiler has to know what type you're checking against so that it can write the check that I gave pseudocode for above. 你要求的是不可能的原因是编译器必须知道你正在检查什么类型,以便它可以编写我上面给出伪代码的检查。 Without knowing what t is, there's no way to know what the static type of s should be, and no way to check whether it's right. 不知道什么t是,有没有办法知道的静态类型是什么s应该的,没有办法检查它是否是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM