How to cast an interface to a typed variable dynamically
Asked Answered
A

1

32

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

Actuate answered 15/1, 2015 at 19:55 Comment(6)
There's no "casting" in go. See type switchPeriphrastic
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.Buzzard
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?Pharyngeal
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.Oswin
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.Alluvion
Refer this : medium.com/@utter_babbage/…Curkell
C
18

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
}
Choir answered 15/1, 2015 at 20:17 Comment(4)
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?Actuate
@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.Periphrastic
@Actuate 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.Willdon
@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).Actuate

© 2022 - 2024 — McMap. All rights reserved.