如何在Scala中使用TypeTag实现该通用函数?

如何在Scala中使用TypeTag实现该通用函数?,scala,types,reification,Scala,Types,Reification,假设我需要编写一个函数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

假设我需要编写一个函数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来实现它吗?

不,应该使用typeclass模式。这样,在编译时而不是运行时解析类型,这样更安全

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,它将无法编译。

否,您应该使用typeclass模式。这样,在编译时而不是运行时解析类型,这样更安全

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,则它将无法编译。

感谢您的快速响应。我猜TypeTag[T]在编译时也可用。如果T不是Int、Double、Boolean,我需要convert[T]返回None怎么办?@Michael,你可以定义一个默认的隐式值,如下所示:def convert[T]s:Stringimplicit converter:converter for[T]=nonecoverter[T],其中def nonecoverter[T]:converter for[T]=。。。它总是不返回任何值。这样,如果没有隐式可用,将使用默认值;但是,如果T是Int、Double或Boolean,则将使用相应的隐式而不是默认值。@Vladimitmaveev非常感谢您的建议!我不喜欢反射,但我处理的是大量使用反射的遗留问题。这就是为什么我现在不能摆脱它。@Michael,你为什么想要它?你知道T是什么,如果你不想要,就用None。我不理解这个用例。感谢您的快速响应。我猜TypeTag[T]在编译时也可用。如果T不是Int、Double、Boolean,我需要convert[T]返回None怎么办?@Michael,你可以定义一个默认的隐式值,如下所示:def convert[T]s:Stringimplicit converter:converter for[T]=nonecoverter[T],其中def nonecoverter[T]:converter for[T]=。。。它总是不返回任何值。这样,如果没有隐式可用,将使用默认值;但是,如果T是Int、Double或Boolean,则将使用相应的隐式而不是默认值。@Vladimitmaveev非常感谢您的建议!我不喜欢反射,但我处理的是大量使用反射的遗留问题。这就是为什么我现在不能摆脱它。@Michael,你为什么想要它?你知道T是什么,如果你不想要,就用None。我不理解这个用例。