Golang: cast an interface to a typed variable dynamically
30,971
No you can't. Go is a static typed language. The type of a variable is determined at compile time.
If you want to determine dynamically the type
of an interface{}
you could use type switching:
var t interface{}
t = functionOfSomeType()
switch t := t.(type) {
default:
fmt.Printf("unexpected type %T", t) // %T prints whatever type t has
case bool:
fmt.Printf("boolean %t\n", t) // t has type bool
case int:
fmt.Printf("integer %d\n", t) // t has type int
case *bool:
fmt.Printf("pointer to boolean %t\n", *t) // t has type *bool
case *int:
fmt.Printf("pointer to integer %d\n", *t) // t has type *int
}
Related videos on Youtube
Author by
orcaman
Updated on June 08, 2020Comments
-
orcaman almost 4 years
In go, is it possible to cast variables dynamically somehow?
For example, if a simple cast would be:
var intAge = interfaceAge.(int)
What if I do not know that age is an int in advance? A simple way of writing it would be
var x = getType() var someTypeAge = interfaceAge(.x)
Is there a way of achieving something like this? The reflect package gives some ways of determining or casting a type at runtime - but I couldn't find anything like the above mentioned (a generic scheme that would work for all types).
-
JimB over 9 yearsThere's no "casting" in go. See type switch
-
fuz over 9 yearsWhen do you not know what type
x
has? Go is a language with static types. The type of a variable is always known at compile time. The type of a variable might be an interface type though. -
Chris Pfohl over 9 yearsYou're looking for a type switch which lets you determine your behavior based on a (static) list of types. There's almost certainly a way todo whatever you're hoping to, can you elaborate on what you're trying?
-
Dave C about 9 yearsSee the spec/documentation. If, and only if,
foo
is an interface type, you can dox := foo.(int)
(or more generallyfoo.(T)
. It's a type assertion and it will panic at runtime if the interface doesn't hold the asked for type. You can usex, ok := foo.(int)
where x will be the zero value andok
will be false if the type assertion failed. -
Brent Bradburn over 4 yearsThe OP doesn't mention type assertions by name, but is clearly aware of that capability (that's what the initial example is showing). The question here is about a dynamic selection of an arbitrary type. The equivalent effect is, in fact, achievable by direct assignment (but nothing is gained):
someTypeAge := interfaceAge
. You can pass around data of typeinterface{}
to your heart's content -- and certain functions, such asfmt.Println(interfaceAge)
, will dynamically process the data. -
infiniteLearner over 3 yearsRefer this : medium.com/@utter_babbage/…
-
-
orcaman over 9 yearsThanks. What I don't get is why the fact that Go is statically typed means that you cannot convert types at runtime. In C#, for example, you can do that, and C# is a static type language as well. Could you please elaborate on this?
-
JimB over 9 years@orcaman: I think you may be confusing interfaces with generics. The type of a value is always known at runtime, because it was known at compile time. Conversions are also well defined in Go.
-
Simon Whitehead over 9 years@orcaman In C#, your type would be inferred using
var
.. just as it is in Go. If you were to define the type explicitly, you would also have to cast it to your required type explicitly (unless you were boxing it). So, I am not sure I get your comparison to C# - its the same situation. Now, if you're talking aboutdynamic
- then that's a whole different beast and certainly does not guarantee compile time type safety. -
orcaman over 9 years@SimonWhitehead thanks. in the c# example, I mean that you could do something like this: var type = obj.GetType(); return Activator.CreateInstance(type) as T; to create an instance of any type without knowing the type in advance. In go, I can get the type dynamically, but I cannot seem to create a variable of that type (without coding an ugly switch statement myself that would cover all types).
-
orcaman over 9 years@fabrizioM - if you add the section about type switching (golang.org/doc/effective_go.html#type_switch) as something that might be close to what I was looking to achieve I will accept the answer (which is correct, yet could be a bit more helpful for people looking to do something similar). Thanks!
-
Dave C about 9 yearsWhy does this not mention type assertions? That seems to be (almost?) exactly what the OP wanted.
-
manit over 3 yearsstill can't do this in 2020. This might be a deal killer for me using Go. A lot of signs of inconsistencies and limitations and stagnation.