質問

" asInstanceOfOption"を書くことは可能ですか?次の(偽の)コードが意図することを行うメソッド?

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&lt ;: Any

または shapeless のTypeableを使用します。これはプリミティブと多くの消去ケースを処理します。

型パラメーターを使用した型キャスト

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