0

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)

}
2
  • 4
    This seems like an XY problem: while there are ways to make this assignment work, it is almost certainly not what you actually need. The problem is not with assigning things (BTW, you shouldn't use vars or nulls in the first place) but with obtaining the actual value to be assigned. If you try to think about your actual real use case rather than generating random strings, you will most likely realize that what you are trying to do here isn't really useful for that. Commented Jul 13, 2022 at 10:53
  • You probably should use a typeclass instead. Commented Jul 13, 2022 at 13:11

2 Answers 2

2

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)
Sign up to request clarification or add additional context in comments.

Comments

0

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)
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.