Home > Back-end >  How to assign value to a generic variable in scala?
How to assign value to a generic variable in scala?

Time:07-13

I have the below function, I am trying to assign a value to the generic variable obj. And getting error: "Expression of type string cannot firm to expected type A". How do I fix this, any pointers would help, thanks.

def getTypedData[A](name: String, typeName: String): DataPoint[A] = {

 var obj: A = null.asInstanceOf[A]

 typeName match {
  case "string" => obj = Random.nextString(5)
 }
 DataPoint(name, obj)

}

CodePudding user response:

It's not clear what you are trying to achieve. But with some tweaks to DataPoint class to avoid null, below snippet could be used as a starting point:

import scala.util.Random
import scala.reflect._

case class DataPoint[A](name: String, obj: Option[A])

def getTypedData[A: ClassTag](name: String): DataPoint[A] = {
  val obj = classTag[A] match {
    case str if str == classTag[String] => Option(Random.nextString(5))
    case int if int == classTag[Int] => Option(Random.nextInt(5))
    case _ => None
  }
  DataPoint(name, obj.asInstanceOf[Option[A]])
}
val data1: DataPoint[String] = getTypedData("name1") //DataPoint(name1,Some(嵍ᔾॹ墊讨))
val data2: DataPoint[Int] = getTypedData("name2") //DataPoint(name2,Some(2))
val data3: DataPoint[Long] = getTypedData("name2") //DataPoint(name2,None)

CodePudding user response:

Since compiler isn't sure that type A is subtype of String or not, it's complaining. If you want to make your above code work, you will have to do something like below:

def getTypedData[A <: String](name: String, typeName: String): DataPoint[A] = {
    var obj: A = null.asInstanceOf[A]

    typeName match {
      case "string" => obj = (Random.nextString(5)).asInstanceOf[A]
    }
    DataPoint(name, obj)
  }

Then compiler would complain if someone tries to call getTypedData with any type which is not subtype of String.

Alternatively, You can do it without using var like below:

def getTypedData[A](name: String, typeName: String): DataPoint[A] = {
val obj =  typeName match {
  case "string" => Some(Random.nextString(5))
  case _ => None
 }

 DataPoint(name, obj.orNull)
}
  • Related