8

私は Scala の isInstanceOf メソッドと asInstanceOf メソッドが好きではありません。これらは長く、asInstanceOf は例外をスローする可能性があるため、組み合わせて使用​​する必要があります。より良い方法は、パターン マッチングを使用することです: Scala: How do I cast a variable? ただし、非常に単純な操作の場合は、比較的長くなる可能性もあります。C# には「is」および「as」演算子があるため、Scala でこれを使用して暗黙の定義を実装したいと考えました。私のコードは次のようになります。

scala> class TypeCast(x:Any){
     | def is[T](t:Class[T]) = t.isInstance(x) 
     | def as[T](t:Class[T]):Option[T] = if(t.isInstance(x)) Option(t.cast(x)) else None
     | }
defined class TypeCast

scala> implicit def TypeCastID(x:Any)=new TypeCast(x)
TypeCastID: (x: Any)TypeCast

scala>  123 as classOf[String]
res14: Option[String] = None

scala> "asd" as classOf[String]
res15: Option[String] = Some(asd)

これには利点が 1 つあります。null オブジェクト パターンを実装しますが、欠点もあります。

  • classOf[T] 演算子を使用する必要があります - 長すぎます

  • このような単純な操作の暗黙的な定義に接続されたオーバーヘッド

したがって、それを使用する実際的な理由はありません。classOf[T] を使用せずにこれを実装する方法はありますか?

4

1 に答える 1

10

TypeCast クラスで作成した定義内で短縮できます。したがって、パラメーターを与える代わりに、型に頼ることができます。これにより、大幅に短縮されます。例として、これは次のようになります。

class TypeCast(x : Any) {
    def is[T : Manifest] = manifest.erasure.isInstance(x)
    def as[T : Manifest] : Option[T] = if (manifest.erasure.isInstance(x)) Some(x.asInstanceOf[T]) else None
}

将来の呼び出しは次のようになります。

scala> 123.as[String]
res0: Option[String] = Some(123)
scala> class A; class B extends A
defined class A
defined class B
scala> new B
res1: B
scala> res1.is[Int]
res2: Boolean = false
scala> res1.as[Int]
res3: Option[Int] = None

更新: タイプチェックエラーを回避するためにマニフェストを追加しました

于 2012-04-25T21:13:42.317 に答える