asInstance [T]但结果为Option [T]

时间:2016-12-09 17:13:13

标签: scala

我有实例和类型,并希望获得Some以防万一,并且None如果没有。

目前我使用自己的实现:

def tryCast[T](o: Any)(implicit manifest: Manifest[T]): Option[T] = {
  val clazz = manifest.runtimeClass.asInstanceOf[Class[T]]
  if (clazz.isAssignableFrom(o.getClass)) {
    Some(o.asInstanceOf[T])
  } else {
    None
  }
}

我可以使用标准库中的任何方法吗?

3 个答案:

答案 0 :(得分:6)

据我所知,此功能没有标准实现。您需要使用自己的实现。但是,不推荐Manifest,您应该使用ClassTag。此外,当存在隐式ClassTag时,编译器允许您使用模式匹配而不是手动检查类。

def tryCast[To: ClassTag](x: Any): Option[To] = x match {
  case thing: To => Some(thing)
  case _ => None
}

上述方法也可以写成如下:

//            "To: ClassTag" desugars to this v parameter, but it has no name
def tryCast[To](x: Any)(implicit tag: ClassTag[To]): Option[To] = x match {
  case thing: To => Some(thing)
  case _ => None
}

答案 1 :(得分:1)

我不确定此类功能,但您可以Try.toOption一起使用:

import scala.util.Try
val name: Any = "tyler"
val name: Any = "tyler"
val maybeString: Option[String] = Try(name.asInstanceOf[String]).toOption
val maybeInt = Try(name.asInstanceOf[Int]).toOption

println(maybeString)
println(maybeInt)

输出

Some(tyler)
None

您可以使用带隐式转换的增强类型更进一步。

答案 2 :(得分:1)

您可能需要TypeTag,例如:

def tryCast[A](o: A)(implicit tpe: Type, ta: TypeTag[A]): Option[A] = ta.tpe =:= tpe match {
      case true => Some(o)
      case false => None
}
implicit val tag = typeOf[Int]
val cast: Option[Int] = tryCast(1)
val cast2: Option[String] = tryCast("hello")
println(cast)
println(cast2)

输出:

>Some(1)
>None

implicit tpe: Type是您想要的匹配type,并使用ta: TypeTag[A] implicit TypeTag获取您的参数类型。

这样,没有cast,更安全。