2010-11-18 12 views
3

スカラの既存のクラスに新しいメソッドを定義する方法が出てきます。既存のクラスにメソッドを挿入する

例えば、私はasInstanceOf[T]方法があまりにも長い名前を持っていると思う、私はまっすぐ前方アプローチが可能as[T].

とそれを交換したい:

class WrappedAny(val a: Any) { 
    def as[T] = a.asInstanceOf[T] 
} 

implicit def wrappingAny(a: Any): WrappedAny = new WrappedAny(a) 

とのより自然な方法はあります少ないコードですか?

scala> class A 

defined class A 

scala> implicit def toA(x: Any): A = x 

toA: (x: Any)A 

scala> toA(1) 

とコンソールがハング:私はこれをしようとすると

はまた、奇妙なことが起こります。 toA(Any)はタイプチェックフェーズに合格すべきではなく、暗黙的でないときは不可能です。また、すべてのコードを外部ソースコードに入れることで同じ問題が発生する可能性があります。どうしてそうなった?それはコンパイラのバグですか(バージョン2.8.0)?

答えて

8

私はそれが一般的に悪いと思われるが、Anyのポンピングへのあなたのアプローチには技術的に問題はない。同様に、asInstanceOfisInstanceOfのように冗長な名前が付けられています。あなたがそれらを使用するのを妨げることです!あなたがしようとしていることを何でもするために、より確実に、静的にタイプセーフな方法があります。 toAの宣言された型がAny => Aで、まだあなたがAny、ないA型を持つxとしてその結果を、定義した:あなたのコンソールがハングする例について

。これはどうやってコンパイルできますか?明白な型エラーが発生すると、コンパイラは問題を解決するために利用可能な暗黙の変換を調べます。この場合、暗黙の変換Any => A ...が必要で、1つを見つけます:toA!無限再帰で、もちろん結果のあなたがそれを使用しようと

implicit def toA(x: Any): A = toA(x) 

...:コンパイラが暗黙的としてそれを再定義されているのでだから、理由toA型チェックがあります。

+0

うわー!これは素晴らしいです。このアイデアはどうやって思いついたのですか?また、asInstanceOf [T]は単なる例です。私は、一般的なケースで動作するシンタックスキャンディーがあるのは不思議です。 –

+0

一般的なルールとして、コードに型エラーがありますが、コンパイラがそれを受け入れると、暗黙の変換が行われています...それがぶら下がっていたという事実が大きな手がかりでした:) –

3

Anyを2番目の例では、Aを返さなければならない関数に渡しています。ただし、Aを返すことはありませんが、同じAnyが渡されます。次にコンパイラは暗黙の変換を適用しようとし、AではなくAnyなどを返します。

あなたが得る暗黙的ではないものとして、TOAを定義する場合:

scala> def toA(x: Any): A = x   
<console>:6: error: type mismatch; 
found : Any 
required: A 
     def toA(x: Any): A = x 
          ^
1

偶然にも、これはScalaの上で議論されてきたが前に示しています。 pimp my classパターンは、それがしていることを実際に少し冗長にしています。おそらく、新しいキーワードを導入することなく構文を消去する方法があるかもしれません。

Scalaの目標の1つは、言語を「言語に追加するのに十分役立つ」という基準を満たしたアイデアの巨大なキルトにするのではなく、ライブラリを通してスケーラブルにすることです。同時に、他のアイデアを、有用であるとは見なされず、かつ/または一般的なものとみなされないようにすることは不可能である。

これまでのところ何も出てこなかったので、その目標に向かって進行中の作業はないと聞いていません。あなたはメーリングリストを通じてコミュニティに参加し、その発展に貢献することができます。

関連する問題