2

My Problem is as follows:

I have a slice of reflect.Value, that was returned from a MethodByName("foo").Call().

now i want to cast the contained values to their types, which i dont know statically, but in form of relflect.Type

Basically what i want to do is:

values[0].Interface().(mytype)

but with reflection

values[0].Interface().(reflect.TypeOf(responseObject))

This gives me the compilation error:

reflect.TypeOf(responseObject) is not a type

Is there a way to do this in go?

Thanks and regards

BillDoor

billdoor
  • 1,999
  • 4
  • 28
  • 54
  • i cant because i don't know the type statically – billdoor Apr 30 '15 at 11:01
  • You switch on reflect.Type.Kind() and call the reflect.Value.{Int,String,Float,...}() accordingly. – Volker Apr 30 '15 at 11:04
  • i cannot do that, because the type of responseObject could be any struct anyone has defined and i don't know ithese – billdoor Apr 30 '15 at 11:12
  • 3
    @billdoor: You should describe in your question what you are planning on doing with the slice of `reflect.Value`s. Because what you are proposing, in its current form, cannot be done. –  Apr 30 '15 at 11:17
  • 2
    @bildor: You do know which types a reflect.Value can be converted to, because this is a _fixed_ list. Of course you cannot do dynamic type casts, but then just find a different design like we tried to explain. The whole ideo of a dynamic type cast is nonsensical as the resulting object _needs_ a static type known at compile time. – Volker Apr 30 '15 at 11:49
  • 1
    if you don't know the type statically, then there's no reason to do a type assertion, and you can leave it in an `interface{}`. If you're doing a type assertion, it's because you have a specific, known type you need. – JimB Apr 30 '15 at 13:13

2 Answers2

4

If you have code using the normal type assertion syntax like:

x := v.(mytype)

Then the compiler knows that the variable x is of type mytype, and generates code accordingly. If the language let you use an expression in place of the type, then the compiler would have no way of knowing what type x is, and consequently no way to generate code that uses that variable.

If you only know the type of value at runtime, then you will need to stick with the reflect.Value API. You can determine the value's type using its Type method, and there are methods that will let you access struct fields, indexes in slices or arrays, etc.

You will only be able to move back to regular syntax when you have a type you know about at compile time.

James Henstridge
  • 42,244
  • 6
  • 132
  • 114
1

What is a cast (type assertion)? It has two effects:

  1. At compile time, the compile-time of the whole type assertion expression is the type casted to.
  2. At runtime, a check is made on the actual runtime type of the value, and if it is not the type casted to, it will generate a runtime error.

Obviously, #1 doesn't make sense for a type that is not known at compile-time, because how can the compile-time type of something depend on something not known at compile time?

You can still do manually do #2 for a type that is not known at compile time. Just get the runtime type of the value using reflect.TypeOf() and compare it against the runtime.Type you have.

newacct
  • 119,665
  • 29
  • 163
  • 224