如何实现在Scala中与TypeTag是通用的功能?(How to implement that g

2019-10-22 10:26发布

假设我需要编写一个函数convert[T]: String => Option[T]如下,它的工作原理:

 import scala.util.Try

 def toInt(s: String): Option[Int] = Try(s.toInt).toOption
 def toDouble(s: String): Option[Double] = Try(s.toDouble).toOption
 def toBoolean(s: String): Option[Boolean] = Try(s.toBoolean).toOption

 // if T is either Int, Double, or Boolean return 
 // toInt(s), toDouble(s), toBoolean(s) respectively

 def convert[T](s: String): Option[T] = ???

我应该使用TypeTag来实现呢?

Answer 1:

不,你应该使用类型类的图案。 这样的类型在编译时间,而不是运行时解决,这是更安全。

trait ConverterFor[T] {
  def convert(s: String): Option[T]
}
object ConverterFor {
  implicit def forInt = new ConverterFor[Int] {
    def convert(s: String) = Try(s.toInt).toOption }
  implicit def forDouble = ...
}

def convert[T](s: String)(implicit converter: ConverterFor[T]): Option[T] =
  converter.convert(s)

正确ConvertorFor在编译时含蓄地解决。 如果你试图调用convert与类型不存在用于隐式ConverterFor可用,它将无法编译。



文章来源: How to implement that generic function with TypeTag in Scala?