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 typeof 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
}
Share:
30,971

Related videos on Youtube

orcaman
Author by

orcaman

Updated on June 08, 2020

Comments

  • orcaman
    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
      JimB over 9 years
      There's no "casting" in go. See type switch
    • fuz
      fuz over 9 years
      When 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
      Chris Pfohl over 9 years
      You'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
      Dave C about 9 years
      See the spec/documentation. If, and only if, foo is an interface type, you can do x := foo.(int) (or more generally foo.(T). It's a type assertion and it will panic at runtime if the interface doesn't hold the asked for type. You can use x, ok := foo.(int) where x will be the zero value and ok will be false if the type assertion failed.
    • Brent Bradburn
      Brent Bradburn over 4 years
      The 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 type interface{} to your heart's content -- and certain functions, such as fmt.Println(interfaceAge), will dynamically process the data.
    • infiniteLearner
      infiniteLearner over 3 years
  • orcaman
    orcaman over 9 years
    Thanks. 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
    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
    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 about dynamic - then that's a whole different beast and certainly does not guarantee compile time type safety.
  • orcaman
    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
    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
    Dave C about 9 years
    Why does this not mention type assertions? That seems to be (almost?) exactly what the OP wanted.
  • manit
    manit over 3 years
    still 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.