2010-12-13 14 views
3
trait Link[This] { 
    var next:This = null 
} 

は、「型の不一致を、見つけ:NULL(ヌル)が必要:この」与え型に "null"を割り当てる前に、型を制約する必要はありますか?

をので、おそらく私は、これはnullを割り当てることができるタイプであることを行っていることを型チェッカーを伝える必要があります。これはどうすればいいですか?

(私はこのような質問をする前に最初に読むべきサイトがあれば、それで私を指すしてください。私は現在、スカラ座でのプログラミングの第2版のプレプリントによる途中だ)

答えて

8

Thisは、nullがそのタイプの有効な値であることをコンパイラに伝える方法であるNullのスーパークラスになるように制約する必要があります。 (実際には、思考を約AnyAnyRefAnyValは、唯一の問題をmuddles - ちょうどあなたが何をしたいのためのコンパイラを頼む!)

trait Link[This >: Null] { 
    var next:This = null 
} 

をしかし、私は、あなたがnullを使用しないことをお勧めしますOption[This]を使用し、影響を与える可能性None - このような構成では、パターンマッチングを使用できるようになります。このフィールドを使用するクライアントは、値を持たないと予想する必要があります。

trait Link[This] { 
    var next:Option[This] = None 
} 
+0

オプションについてはかなり正しいですし、最終的にそのように行くでしょう。しかし、これはもともとJavaでコードをリファクタリングする段階ですが、現在はnullを使用することが多すぎます –

0
trait Link { 
    var next:This = null 
} 

これは動作するはずです。型を持つ特性をパラメータ化する必要がある特定の理由はありますか?

+0

「Link」クラスが彼が書いたスニペットと同じくらい複雑であると思われる特別な理由はありますか? –

+0

はい、理由があります - これは別のクラスに混在しており、そのクラスのリンクリストを作成しています。 –

0

私の最初の考えはうまくいかなかった。なぜ私は分からない。

trait Link[This <: AnyRef] { // Without the type bound, it's Any 
    var next: This = null 
} 

悪いことは最悪になると、常にそこにキャストだ:あなたは他の理由のためにそこにそれを望むかもしれませんが

trait Link[This <: AnyRef] { 
    var next: This = null.asInstanceOf[This] 
} 

をキャストすると、あなたはもはや、コンパイルするには、この特性のためにバインドタイプを必要とするが、 。

+0

私は、 "AnyRef'を拡張して"値としてnullを受け入れる "というのは論理的に異なっているという理由があると信じています.JVM内の現在のすべての型が両方を満たすか否か。 –

+1

'AnyRef'のいくつかのクラスが強制的にnullでないという考えがあるので、うまくいきませんでした。したがって、あなたは 'trait Link [This>:Null <:AnyRef]'を必要とします。しかし、AnyValの中の何も、とにかく 'Null'のスーパークラスなので、' Link [This::Null] 'で十分です。 –

関連する問題