Scala - создать имя метода из универсального типа? - PullRequest
2 голосов
/ 25 апреля 2011

У меня есть следующий метод:

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
  }

Можно ли как-то упростить это, чтобы он смотрел на тип T (например, Int, Long и т. Д.) И использовал его для вызова "to (метод toInt, toLong и т. д.)?

В качестве дополнительного вопроса, могу ли я как-то ограничить T только Int и Long, а не подклассом AnyVal?

Спасибо, Джон

1 Ответ

10 голосов
/ 25 апреля 2011

Если вы хотите ограничить 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 
}

Тогда ваш метод:

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

<ч /> Однако я бы лично переписал подпись этого метода как:

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

И тогда пользователи будут использовать getOrElse default на сайте использования. Например:

natural[Int]("42") getOrElse 23
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...