简体   繁体   English

Scala TypeTag反射返回类型T

[英]Scala TypeTag Reflection returning type T

I currently have this: 我目前有这个:

def stringToOtherType[T: TypeTag](str: String): T = {
  if (typeOf[T] =:= typeOf[String])
    str.asInstanceOf[T]
  else if (typeOf[T] =:= typeOf[Int])
    str.toInt.asInstanceOf[T]
  else
    throw new IllegalStateException()

I would REALLY like to not have the .asInstanceOf[T] if possible (runtime). 如果可能(运行时),我真的很想没有.asInstanceOf [T]。 Is this possible? 这可能吗? Removing the asInstanceOf gives me a type of Any, which makes sense, but since we are using reflection and know for sure that I am returning a value of type T, I don't see why we can't have T as a return type, even if we are using reflection at runtime. 删除asInstanceOf可以使我得到Any类型,但这很有意义,但是由于我们使用了反射并且可以确定我返回的是T类型的值,所以我不明白为什么不能将T作为返回类型,即使我们在运行时使用反射。 The code block there without asInstanceOf[T] is never anything but T. 没有asInstanceOf [T]的代码块永远不是T。

You should not be using reflection here. 您不应该在这里使用反射。 Instead implicits, specifically the type-class pattern, provide a compile-time solution: 相反,隐式(特别是类型类模式)提供了编译时解决方案:

trait StringConverter[T] {
  def convert(str: String): T
}

implicit val stringToString = new StringConverter[String] {
  def convert(str: String) = str
}

implicit val stringToInt = new StringConverter[Int] {
  def convert(str: String) = str.toInt
}

def stringToOtherType[T: StringConverter](str: String): T = {
  implicitly[StringConverter[T]].convert(str)
}

Which can be used like: 可以像这样使用:

scala> stringToOtherType[Int]("5")
res0: Int = 5

scala> stringToOtherType[String]("5")
res1: String = 5

scala> stringToOtherType[Double]("5")
<console>:12: error: could not find implicit value for evidence parameter of type StringConverter[Double]
              stringToOtherType[Double]("5")
                                       ^

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM