Tom Antony
Tom Antony

Reputation: 79

how can i do dynamic casting of a variable from one type to another in Scala

I would like to do dynamic casting for a scala variable, the casting type is stored in a different variable or in the database or provided by the user.

I am new to Scala and have mainly done coding on python. Here we are trying to take Any type input and query the type of the variable as per the type saved in DB eg.: "String/Int" and user-defined classes and cast them before any future processing.

in python:

eval("str('123')")

in scala I have tried

var a = 123.05
a.asInstanceOf['Int']

gives me error

error: identifier expected but string literal found.

And I want the code to be something as follows:

var a = 123.05
var b = "Int"
a.asInstanceOf[b]

gives me error

error: not found: type b

Upvotes: 1

Views: 1513

Answers (2)

Dominic Egger
Dominic Egger

Reputation: 1016

Ok so I have to be fairly exhaustive here because the stuff you're trying to do is tricky due to the static vs dynamic typing difference of scala and python.

First what you're doing in Python is not type casting but rather a conversion.

str(12)

in python takes the integer value 12 and converts it to a (UTF-8 ? dunno in python) string. The same thing in scala would be

12.toString

typecasting in the meantime is basically a pinky promise to the compilers typechecker that you know more than it and it should just believe you. It also should be avoided like the pest because you basically drop all the safety that static typechecking gives you. However there are certain cases where it is unavoidable

in a bit more fundamental terms. lets say you have the following scala snippet

sealed trait Foo
final case class Bar(i:Int) extends Foo
final case class Baz(s:String) extends Foo

val f:Foo = Bar(2)
//won't work because the compiler thinks f is of type Foo due to the type ascription bove
println(f.i)
//will work
println(f.asInstanceOf[Bar].i)

the Type Foo can be either Bar or Baz (because of the sealed and final, this is called an ADT) but we specifically told the compiler to treat f as a Foo which means we forgot which specific type it was. this is the case where you could use typecasting, note that we don't convert but rather tell the compiler that it is actually a Bar

Now this all happens during compile time which means you can't cast according to a runtime value like this

var a = 123.05
var b = "Int"
a.asInstanceOf[b]

Now as I understand you have some sort of stringly typed input and need to convert it according to some schema. The scalafiddle below has an example how you could do this: https://scalafiddle.io/sf/i97WZlA/0

However note that this makes use of some fairly advanced concepts in scala to ensure the types line up.

This will also work https://scalafiddle.io/sf/i97WZlA/1 but note that we lose all the type information requiring us to do a typecast if we want to do anything meaningful with out

EDIT/ADDENDUM: I thought I should also do an example on how to consume such values and make the schema dynamic.

https://scalafiddle.io/sf/i97WZlA/2

As a final note be warned that this is getting close to the limits what the compiler can do and necessitates a lot of boxing and unboxing to carry along the type information (in SchemaValue) also it's not stacksafe and has lackluster errorhandling. this solution would require some serious engineering to make viable but it should get the idea across

Upvotes: 2

Tim
Tim

Reputation: 27421

If you have a String value, then you can use toInt or toDouble to parse that string:

val s = "123.05"
val i = s.toInt
val d = s.toDouble

If you have an Any value then it is best to use match to convert it:

val a: Any = ...

a match {
  case i: Int => // It is an Int
  case d: Double => // It is a Double
  case _ => // It is a different type
}

If all else fails you can explicitly pick a type, but this is not good practice:

val i = a.asInstanceOf[Int]

Any decent database framework will give you the ability to read and write values of specific types, so this should not be a problem with the right library.

Upvotes: 0

Related Questions