Reputation: 1354
I want to have a method getInstance
which takes a string value and return an instance of object, defined as generic in method signature
def getInstance[T](dataStr: String): Option[T] = {
T match {
case typeOf[String] => Some(dataStr) // if type of T is String
case typeOf[Integer] => Some(dataStr.toInt) // if type of T is Integer
case typeOf[Boolean] => Some(dataStr.toBoolean) // if type of T is Boolean
case _ => throw new NoSuchElementException()
}
}
How can I write same in Scala?
Scala version: 2.11
Upvotes: 2
Views: 78
Reputation: 22895
I believe you are trying to use the Scala's ClassTag
.
import scala.reflect.{ClassTag, classTag}
import scala.util.Try
def getInstance[T](dataStr: String)(implicit T: ClassTag[T]): Option[T] = T match {
case _ if T == classTag[String] => Some(dataStr).flatMap(T.unapply)
case _ if T == classTag[Int] => Try(dataStr.toInt).toOption.flatMap(T.unapply)
case _ if T == classTag[Long] => Try(dataStr.toLong).toOption.flatMap(T.unapply)
case _ if T == classTag[Float] => Try(dataStr.toFloat).toOption.flatMap(T.unapply)
case _ if T == classTag[Double] => Try(dataStr.toDouble).toOption.flatMap(T.unapply)
case _ if T == classTag[Boolean] => Try(dataStr.toBoolean).toOption.flatMap(T.unapply)
case _ => None
}
Upvotes: 1
Reputation: 27421
A typeclass is probably the best solution.
trait FromString[T] {
def apply(s: String): T
}
object FromString {
implicit object IntString extends FromString[Int] {
def apply(s: String) = s.toInt
}
implicit object DoubleString extends FromString[Double] {
def apply(s: String) = s.toDouble
}
implicit object BooleanString extends FromString[Boolean] {
def apply(s: String) = s.toBoolean
}
}
def getInstance[T](dataStr: String)(implicit from: FromString[T]): Option[T] =
Some(from(dataStr))
val a = getInstance[Int]("1")
val b = getInstance[Double]("1.0")
val c = getInstance[Boolean]("true")
This will give compile-time checking of valid types for getInstance
and will return the appropriate Option
type.
Upvotes: 5
Reputation: 3638
You can use pattern matching in scala which solves the problem elegantly.
def getInstance[T >: Any](dataStr: String, myType : T) : Option[T] ={
myType match {
case x @ Int => Option(dataStr.toInt)
case x @ Double => Option(dataStr.toDouble)
case x @ Float => Option(dataStr.toFloat)
case _ => throw new NoSuchElementException()
}
}
On invoking the function,
getInstance("1",Int)
getInstance("1",Double)
getInstance("1",Float)
will give you result as
res0: Option[Any] = Some(1)
res1: Option[Any] = Some(1.0)
res2: Option[Any] = Some(1.0)
Upvotes: 2