0

I have code that returns a value as Any. I have a way to get the actual type of this value. This is part of a very reflection-oriented solution.

    // Reflecting on a class I have info about its constructor fields:
    val fieldMembers: fieldMembersByName: ListMap[String,ClassFieldMember] = ...

    // ClassField member has a method valueIn(inst:T): Any, where T is the type
    // of the parent class

    val nameField = fieldMembers("name").valueIn(personObject)

    // This obtains the value of some instance's (personObject's) name field,
    // but to Scala the type of nameField is Any.  I need to cast it, but to what?

    val realType: Type = ...  // a bunch of ugly reflection that returns the acutal
    // type of the name field, i.e. String here

What I'm looking for is the equivalent of the (syntactically invalid):

val purifiedValue = nameField.asInstanceOf[realType]
Dmytro Mitin
  • 48,194
  • 3
  • 28
  • 66
Greg
  • 10,696
  • 22
  • 68
  • 98
  • 4
    Can you provide more context? `asInstanceOf` is how you cast things, but you really shouldn't need it. Likewise, there's probably a better way to do things than returning an `Any`. Additionally, without the compiler error or a compilable example, it's a bit hard to debug. – Ethan Aug 05 '19 at 21:18
  • 1
    @Greg as Ethan said, the first step is avoid something to return `Any`, if you can not change that... well, then you can only either **pattern matching** _(but it may not be enough for complex cases)_ or `asInstanceOf`. – Luis Miguel Mejía Suárez Aug 05 '19 at 21:35
  • 3
    What do you mean by `Scala syntax won't allow aValue.asInstanceOf[realType]`? – SwiftMango Aug 05 '19 at 21:36
  • realType is a value, not a type, so asInstanceOf[realType] won't compile. The _value_ of realType might be String or something, but realType itself is not a type but a value. – Greg Aug 05 '19 at 22:12
  • If the type is a value, that comes from runtime, using reflection. You really can not do too much here... How will you even use the casted value, if you do not even know which type will it be until runtime. You can only continue to use reflection to manipulate that object. – Luis Miguel Mejía Suárez Aug 05 '19 at 22:16
  • 1
    Any value's type in Scala is known at compile time. It doesn't make sense to have `String or something` as the type. Even with reflection, the type is known. If you are unsure about the type, you are doing something wrong. If you have a singleton object with no class symbol, you can do `nameField.asInstanceOf[realType.type]` – SwiftMango Aug 05 '19 at 22:30
  • It doesn't look like reflection is the right solution here. Can you give us the actual problem you're trying to solve? This sounds like a good use case for type classes, but it's hard to provide guidance without knowing what you actually want to do. – Ethan Aug 06 '19 at 17:30

1 Answers1

2

This is not possible for the simple reason that the type of a variable is defined at compile time not at run time.

So when you write

val purifiedValue = nameField.asInstanceOf[realType]

the compiler needs to decide what is the type of purifiedValue. There is no way that it can do this if realType is not defined until run time.

It is also not clear how this would help even if it did work. What are you going to do with purifiedValue once you have assigned it? You can't call any methods on it because you don't know what type it is going to have. You can't pass it to a function because you don't know if the type matches the argument type of the function argument. The only things that you can do with purifiedValue are the things you can do with Any, which is the type it had in the first place.

Tim
  • 26,753
  • 2
  • 16
  • 29