Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang how to do type assertion for unknown interface?

Tags:

go

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?

like image 787
Marconi Avatar asked Feb 01 '14 08:02

Marconi


1 Answers

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.

like image 164
joshlf Avatar answered Sep 20 '22 08:09

joshlf