문제

다음 (Bogus) 코드에 의해 의도 된 작업을 수행 할 "asinstanceoftion"메소드를 작성할 수 있습니까?

def asInstanceOfOption[T](o: Any): Option[T] =
   if (o.isInstanceOf[T]) Some(o.asInstanceOf[T]) else None 
도움이 되었습니까?

해결책

편집하다 아래는 나의 원래 대답이지만 지금 이걸 달성 할 수 있습니다.

def asInstanceOfOption[T: ClassTag](o: Any): Option[T] = 
  Some(o) collect { case m: T => m}

매니페스트를 사용하여 T ~이다 문질러 지우는 컴파일 시간에 :

scala> import scala.reflect._
import scala.reflect._

scala> def asInstanceOfOption[B](x : Any)(implicit m: Manifest[B]) : Option[B] = {
   | if (Manifest.singleType(x) <:< m)
   |   Some(x.asInstanceOf[B])
   | else
   |   None
   | }
asInstanceOfOption: [B](x: Any)(implicit m: scala.reflect.Manifest[B])Option[B]

그런 다음 사용될 수 있습니다.

scala> asInstanceOfOption[Int]("Hello")
res1: Option[Int] = None

scala> asInstanceOfOption[String]("World")
res2: Option[String] = Some(World)

당신은 심지어 사용할 수도 있습니다 암시 적 전환 이것을 사용할 수 있도록하기 위해 Any. 메소드 이름을 선호한다고 생각합니다 matchInstance:

implicit def any2optionable(x : Any) = new { //structural type
  def matchInstance[B](implicit m: Manifest[B]) : Option[B] = {
    if (Manifest.singleType(x) <:< m)
      Some(x.asInstanceOf[B])
    else
      None
  }   
}

이제 다음과 같은 코드를 쓸 수 있습니다.

"Hello".matchInstance[String] == Some("Hello") //true
"World".matchInstance[Int] == None             //true    

편집 : 2.9.x에 대한 업데이트 된 코드는 사용할 수 없습니다. Any 그러나 단지 AnyRef:

implicit def any2optionable(x : AnyRef) = new { //structural type
  def matchInstance[B](implicit m: Manifest[B]) : Option[B] = {
    if (Manifest.singleType(x) <:< m)
      Some(x.asInstanceOf[B])
    else
      None
  }   
}

다른 팁

다음은 Oxbow_lake의 업데이트 된 답변에 대한 자세한 내용입니다. Scala 2.10이 필요하도록 추가 업데이트 :

// Implicit value class
implicit class Castable(val obj: AnyRef) extends AnyVal {
  def asInstanceOfOpt[T <: AnyRef : ClassTag] = {
    obj match {
      case t: T => Some(t)
      case _ => None
    }
  }
}

이것은 다음과 같이 사용할 수 있습니다.

"Hello".asInstanceOfOpt[String] == Some("Hello") // true
"foo".asInstanceOfOpt[List[_]] == None // true

그러나 다른 답변에서 언급했듯이 이것은 권투 문제로 인해 프리미티브에 효과적이지 않으며 삭제로 인해 제네릭을 처리하지 않습니다. 프리미티브를 허용하지 않기 위해 나는 제한했다 obj 그리고 T 확장하려면 AnyRef. 프리미티브를 처리하는 솔루션의 경우 Matt R의 후속 질문에 대한 답변을 참조하십시오.

asinstanceofopt [t]를 쓰는 방법 [t <:

또는 사용 엉성한많은 삭제 사례뿐만 아니라 프리미티브를 처리하는 유형성 :

유형 매개 변수를 사용하여 주조 유형

Oxbow_lakes의 답변 ('09 년 후반)을 쓸 당시에는 믿습니다. scala.util.Try 그러나 지금 사용할 수 없었지만 (예 : 2.10 기준) 나는 생각합니다. scala.util.Try 이 작업을 수행하는 선호하는 (또는 적어도 잘 보이는) 방법입니다.

scala> Try((3).asInstanceOf[String]).toOption
res0: Option[String] = None

scala> Try("hello".asInstanceOf[String]).toOption
res1: Option[String] = Some(hello)
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top