Bala
Bala

Reputation: 11244

How to find instance of a value type in Scala?

I know isInstanceOf can be used to find value type, but how do I find the type of 'str'?

What type is it?

scala> val str = ("Scala", "Elixir","Spark")
str: (String, String, String) = (Scala, Elixir, Spark)

The following throws an error (exclude Any/AnyRef etc for now):

scala> str.isInstanceOf[List]
<console>:13: error: type List takes type parameters
       str.isInstanceOf[List]

scala> str.isInstanceOf[String]
<console>:13: warning: fruitless type test: a value of type (String, String, String) cannot also be a String (the underlying of String)
       str.isInstanceOf[String]
                       ^
res9: Boolean = false

I can check it this way but is there a name for this?

scala> str.isInstanceOf[(String, String, String)]
res12: Boolean = true

Upvotes: 3

Views: 30656

Answers (5)

Joseph
Joseph

Reputation: 160

This method can help you get the type of any val/var at runtime, it's also works in compiled code.

import scala.reflect.runtime.universe._

def printType[T](x: T)(implicit tag: TypeTag[T]): Unit = println(tag.tpe.toString)

printType(List[Int](1,2,3))  // output: List[Int]
printType(("xxx", 123, 0.1)) // output: (String, Int, Double)
printType(2)                 // output: Int

Upvotes: 2

Jasper-M
Jasper-M

Reputation: 15086

The modern (meaning Scala 2.10 or later), Scala way of programmatically getting the compile time type of something is using a TypeTag.

scala> import scala.reflect.runtime.universe._
import scala.reflect.runtime.universe._

scala> def getType[T: TypeTag](value: T) = typeOf[T]
getType: [T](value: T)(implicit evidence$1: reflect.runtime.universe.TypeTag[T])reflect.runtime.universe.Type

scala> val str = ("Scala", "Elixir","Spark")
str: (String, String, String) = (Scala,Elixir,Spark)

scala> println(getType(str))
(java.lang.String, java.lang.String, java.lang.String)

scala> getType(str) <:< typeOf[(String,String,String)]
res1: Boolean = true

scala> getType((1,2,3)) <:< typeOf[(String,String,String)]
res2: Boolean = false

getClass will give your the erased runtime class. isInstanceOf[T] will test whether the erased runtime class is the same as or a subclass of the erased runtime class of T.

And "erased" means that the following evaluates to true.

(1,2,3).isInstanceOf[(String,String,String)]

"runtime" and "compile time" mean that this is true:

val a: Any = (1,2,3)
a.isInstanceOf[(_,_,_)]

while this is false:

val a: Any = (1,2,3)
getType(a) <:< typeOf[(Int,Int,Int)]

Upvotes: 2

Alexey Svyatkovskiy
Alexey Svyatkovskiy

Reputation: 646

Yet another way to determine a type programmatically is using Manifest:

scala> def getType[T: Manifest](t: T): Manifest[T] = manifest[T]
getType: [T](t: T)(implicit evidence$1: Manifest[T])Manifest[T]

scala> val str = ("Scala", "Elixir","Spark")
str: (String, String, String) = (Scala,Elixir,Spark)

scala> getType(str)
res0: Manifest[(String, String, String)] = scala.Tuple3[java.lang.String, java.lang.String, java.lang.String]

Upvotes: 2

fabfas
fabfas

Reputation: 2228

How to determine val type programmatically?

For instance, you want to know the type of the value is some specific type?

// assign x value
val x: Any = "this is string"

// custom function evaluate type
def f[T](v: T) = v match {
  case _: Int    => println("Int")
  case _: String => println("String")
  case _         => println("Unknown")
}

// determine val type
f(x)

Upvotes: 2

Nagarjuna Pamu
Nagarjuna Pamu

Reputation: 14825

Use :type in scala repl to find type

Actual type is Tuple3[String, String, String]

str.isInstanceOf[Tuple3[String, String, String]]

Scala REPL

scala> val str = ("Scala", "Elixir","Spark")
str: (String, String, String) = (Scala,Elixir,Spark)

scala> :type str
(String, String, String)

scala> str.isInstanceOf[Tuple3[String, String, String]]
res2: Boolean = true

scala> str.getClass
res3: Class[_ <: (String, String, String)] = class scala.Tuple3

Upvotes: 5

Related Questions