저는 Scala TypeTag를 가지고 놀고 있습니다. TypeTag 매개 변수를 사용하여 함수를 재귀 적으로 호출하고 싶습니다. 다음은 내가하려는 작업의 간단한 예입니다.
import scala.reflect.runtime.universe._
object TypeTagTest extends App {
def intValue[T](value: T)(implicit tag: TypeTag[T]): Int = {
tag.tpe match {
// integer
case intType if intType <:< typeOf[Int] =>
value.asInstanceOf[Int]
// string
case stringType if stringType <:< typeOf[String] =>
value.asInstanceOf[String].toInt
// option of either string or integer
case optionType @ TypeRef(_, _, typeArg::Nil) if optionType <:< typeOf[Option[_]] =>
println(s"Unwrapped type is $typeArg")
val option = value.asInstanceOf[Option[_]]
option.map { optionValue =>
// how to pass the typeArg here?
intValue(optionValue)
}.getOrElse(0)
}
}
println(intValue(1))
println(intValue("1"))
println(intValue(Some("1")))
}
이 코드는 다음을 컴파일하고 실행합니다.
1
1
Exception in thread "main" scala.MatchError: Any (of class scala.reflect.internal.Types$TypeRef$$anon$6)
at TypeTagTest$.intValue(TypeTagTest.scala:7)
at TypeTagTest$$anonfun$intValue$2.apply(TypeTagTest.scala:19)
at TypeTagTest$$anonfun$intValue$2.apply(TypeTagTest.scala:18)
at scala.Option.map(Option.scala:145)
몇 가지 질문 :
재귀 문제가 아닙니다. "Unwrapped type ..."줄이 인쇄되지 않습니다. 문제는 optionType
이 경우 확장 Some[String]
되는 엄격한 하위 유형이 아니라는 Option[_]
것 Option[A] forSome {type A}
입니다.
이 특정 인스턴스에서 공변 성이기 optionType <:< Option[Any]
때문에 여부를 테스트하고 싶을 것 Option
입니다. 또는의 첫 번째 인수 TypeRef
가 Option
.
이 문제를 수정 한 후에 TypeTag
는 항상 컴파일러에 의해 생성되기 때문에 매개 변수 에 대한를 얻을 수 없다고 생각합니다 Type
.
def intValueInner(value: Any, tpe: Type) = tpe match {
...
case optionType @ TypeRef(_, _, typeArg::Nil) if optionType <:< typeOf[Option[Any]] =>
value.asInstanceOf[Option[_]].map(v => intValueInner(v, typeArg)).getOrElse(0)
}
def intValue[T: TypeTag](t: T) = intValueInner(t, typeOf[T])
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다