开发者

Scala - construct method name from generic type?

开发者 https://www.devze.com 2023-02-28 19:32 出处:网络
I have the following method: def toNumber[T <: AnyVal](value:String, default:T)(implicit n: Numeric[T]):T = {

I have the following method:

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
  }

Is it possible to streamline this somehow so it looks at the type of T (e.g. Int, Long, etc.) and uses it to call the right "to" method (e.g. toInt, toLon开发者_StackOverflow社区g, etc.)?

As a bonus question, can I somehow limit T to just Int and Long rather than any subclass of AnyVal?

Thanks, John


If you want to limit T to specific numeric instances, it might be a good idea to provide your own typeclass (thus providing an answer to your initial question):

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 
}

Then your method:

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


However, I would personally re-write this method signature as:

def natural[T : Natural](value : String) : Option[T]

And then users would use getOrElse default at the use-site. For example:

natural[Int]("42") getOrElse 23
0

精彩评论

暂无评论...
验证码 换一张
取 消