Golang如何为未知界面输入断言? [英] Golang how to do type assertion for unknown interface?

查看:123
本文介绍了Golang如何为未知界面输入断言?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道我可以通过反射来获取对象的值,然后使用type assertion来获取实际的对象:

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

但是如果我不知道对象的类型是 User ,我怎么能输入assertion?
说这是在一个函数内,如:

  func Foo(obj interface {})bool {
// out:= reflect.ValueOf(obj).Elem().interface()。(...)
返回== * obj
}

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

Foo 函数中,您永远不会知道实际将传递哪种类型的对象,因此如何完成类型断言?

解决方案

你不能。类型断言允许你利用静态类型检查语言给你,即使你有一个接口,其类型没有被静态检查。它基本上是这样的:

你有一些静态类型的变量 s ,它的类型为 T 。编译器通过拒绝编译来强制保证 s 始终具有类型 t ,如果您尝试使用<$ c

你也有一些接口变量,<$ c> s 就好像它是一个不同的类型,因为这会破坏保证。 C $ C>我。编译时不知道 i 的类型,因此编译器无法保证将 i 分配给 s 不会破坏 s 类型为 t 。然而,你可以做的是类型断言。类型断言通过说:好吧,我会在运行时检查,并且只在类型匹配时才执行分配来解决这个问题。编译器可以这样做,因为它知道只有类型匹配时才会发生赋值,这意味着它仍然可以保证 s 的类型为。所以基本上在运行时会发生什么:

  if(我有类型t){
s = i
} else {
s = t {} //零值t
}

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


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? 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?

解决方案

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. 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.

You also have some interface variable, 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. 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. 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.

这篇关于Golang如何为未知界面输入断言?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆