Scala:根据参数类型设置值

时间:2016-04-23 13:47:27

标签: scala generics reflection

我有一个与scala implicit相关的初学者问题:

class Box[T](implicit tag: ClassTag[T]) {
  var value = None: Option[Any]

  def pickValueUsingTypeOfT : Unit = {
    val list = List("string", 1, new myClass(1D) )
    println(s"type of  has type arguments $tag")
    //value = Some ( find right element from the 'list' )
  }
}

class myClass(double: Double) {}


object Setter {

  def main(args: Array[String]) {
    val n: Box[String] = new Box[String]
    n.pickValueUsingTypeOfT
  }
}

目标是根据value的类型设置T

1 个答案:

答案 0 :(得分:1)

你不需要反思这样的解决方案。您需要typeclass(例如Numeric)。

trait Foo[T] {
  def aProp: String
  def aFun(v: T): Int
}

object Foo {
  // default instances

  object StrFoo extends Foo[String] {
    // for T = String
    val aProp = "Bar"
    def aFun(v: String) = v.length
  }

  object LongFoo extends Foo[Long] {
    val aProp = "Lorem"
    def aFun(v: Long) = v.toInt
  }
}

所以你的功能可以定义如下。

def pickValueUsingTypeOfT[T](implicit resolved: Foo[T]) = ???

然后它可以用于默认实例:

pickValueUsingTypeOfT[String].aProp
pickValueUsingTypeOfT[Long].aFun(123L)

如果它被调用了不支持的类型,编译器会发现这个问题并帮助你(比运行时反射更好):

pickValueUsingTypeOfT[Byte] // compiler error

可以定义额外的实例。

val localV = "value"

implicit val byteFoo: Foo[Byte] = new Foo[Byte] {
  def aProp: String = localV
  def aFun(v: Byte) = v.toInt * 10
}

pickValueUsingTypeOfT[Byte].aFun(456.toByte)
// now is ok with byteFoo