Scala - 从泛型类型构造方法名称?

jxs*_*ord 2 generics scala

我有以下方法:

def toNumber[T <: AnyVal](value:String, default:T)(implicit n: Numeric[T]):T = {
    val str = value.trim
    var s = n.zero
    if (value.trim.isEmpty) {
      default
    } else {
      if (default.isInstanceOf[Long])
        s = n.plus(n.zero,str.toLong.asInstanceOf[T])
      else if (default.isInstanceOf[Int])
        s = n.plus(n.zero,str.toInt.asInstanceOf[T])
    }
    s
  }
Run Code Online (Sandbox Code Playgroud)

是否有可能以某种方式简化这一点,以便它查看T的类型(例如Int,Long等)并使用它来调用正确的"to"方法(例如toInt,toLong等)?

作为一个额外的问题,我能以某种方式将T限制为Int和Long而不是AnyVal的任何子类吗?

谢谢,约翰

oxb*_*kes 10

如果要限制T特定的数字实例,最好提供自己的类型类(从而为初始问题提供答案):

trait Natural[T] { def from(s : String) : T }
implicit object IntNatural = new Natural[Int] { 
  def from(s : String) = s.toInt 
}
implicit object LongNatural = new Natural[Long] { 
  def from(s : String) = s.toLong 
}
Run Code Online (Sandbox Code Playgroud)

然后你的方法:

def toNumber[T : Natural](value : String, default : T) : T = 
  if (value.trim.isEmpty)
    default
  else 
    implicitly[Natural[T]].from(value.trim)
Run Code Online (Sandbox Code Playgroud)


但是,我个人会将此方法签名重新编写为:

def natural[T : Natural](value : String) : Option[T]
Run Code Online (Sandbox Code Playgroud)

然后用户将getOrElse default在使用现场使用.例如:

natural[Int]("42") getOrElse 23
Run Code Online (Sandbox Code Playgroud)