Golang how to do type assertion for unknown interface?

huangapple go评论75阅读模式
英文:

Golang how to do type assertion for unknown interface?

问题

我理解了,你想知道如何在不知道对象类型的情况下进行类型断言。在Foo函数中,你无法知道实际传递的对象类型,那么如何完成类型断言呢?

你可以使用类型断言的另一种形式,即使用switch语句进行类型判断和转换。以下是修改后的代码示例:

func Foo(obj interface{}) bool {
    switch v := obj.(type) {
    case User:
        return v == *obj.(*User)
    case AnotherType:
        // 处理另一种类型的断言
    default:
        // 处理其他类型或未知类型的情况
    }
    return false
}

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

switch语句中,根据obj的实际类型进行匹配,并执行相应的类型断言和处理逻辑。你可以根据需要添加更多的类型判断分支。

希望这可以帮助到你!如果还有其他问题,请随时提问。

英文:

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?

答案1

得分: 13

你无法这样做。类型断言允许你利用语言提供的静态类型检查,即使你有一个接口,其类型没有静态检查。它的工作原理基本上是这样的:

你有一个静态类型的变量s,其类型为t。编译器通过拒绝编译,来强制保证s始终具有类型t,如果你试图将s用作不同类型,那么这将违反这个保证。

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

if (i 的类型是 t) {
    s = i
} else {
    s = t{} // t 的零值
}

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

英文:

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.

huangapple
  • 本文由 发表于 2014年2月1日 16:22:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/21495810.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定