web-dev-qa-db-ja.com

これはScalaでnull参照を初期化する適切な方法ですか?

初期化されていないMyObjectインスタンスがあるとします。

var a:MyObject = null

これはnullに初期化する適切な方法ですか?

50
Geo

代替案

最後の手段としてnullを使用します。既に述べたように、Optionはnullのほとんどの使用法を置き換えます。 nullを使用して、費用のかかる計算でフィールドの遅延初期化を実装する場合は、lazy valを使用する必要があります。

ヌルへの標準的な初期化

つまり、Scalaはnullをサポートします。個人的にSpring Dependency Injectionと組み合わせて使用​​します。

コードは完全に有効です。ただし、var t: T = _を使用してtをデフォルト値に初期化することをお勧めします。 Tがプリミティブの場合、タイプに固有のデフォルトを取得します。それ以外の場合は、nullを取得します。

これはより簡潔であるだけでなく、Tが何であるかを事前に知らない場合に必要です。

scala> class A[T] { var t: T = _ }
defined class A

scala> new A[String].t
res0: String = null

scala> new A[Object].t            
res1: Java.lang.Object = null

scala> new A[Int].t   
res2: Int = 0

scala> new A[Byte].t
res3: Byte = 0

scala> new A[Boolean].t
res4: Boolean = false

scala> new A[Any].t   
res5: Any = null

高度な

Tが無制限の場合、var t: T= nullを使用するとコンパイルエラーになります。

scala> class A[T] { var t: T = null }
<console>:5: error: type mismatch;
 found   : Null(null)
 required: T
       class A[T] { var t: T = null }

TがNULL可能であることの証拠として暗黙的なパラメーターを追加できます-AnyRefのサブタイプではなくNotNullのサブタイプこれは完全ではありません 焼き =、Scala 2.8でも、今のところは好奇心を考慮してください。

scala> class A[T](implicit ev: Null <:< T) { var t: T = null }           
defined class A
61
retronym

正解はnullを使用しないでくださいです。代わりに、オプションタイプを使用します。

var a = None : Option[MyObject]

設定する場合:

a = Some(foo)

そして、それから読みたいときは、なしをテストします:

a match {
  case None => Console.println("not here")
  case Some(value) => Console.println("got: "+value)
}
32
David Crawshaw

デイビッドとレトロニムがすでに述べたように、ほとんどの場合、Optionを使用することをお勧めします。Optionを使用すると、結果なしの状況を処理する必要があることがより明確になります。ただし、Some(x)を返すにはオブジェクトの作成が必要であり、.getまたは.getOrElseの呼び出しはif文よりもコストがかかる可能性があります。したがって、高性能コードでは、Optionを使用することが常に最善の戦略とは限りません(特に、コレクションルックアップコードでは、値を何度も検索し、それに応じて多くのオブジェクトを作成する必要はありません)。繰り返しますが、Webページ全体のテキスト(存在しない可能性があります)を返すようなことをしている場合、Optionを使用する理由はありませんnot

また、nullを使用してジェネリックに関するレトロニムのポイントを追加するだけで、本当にnullである必要がある場合は、これを完全に焼き付けた方法で実行できます。

class A[T >: Null] { var t: T = null }

これは2.7および2.8で機能します。それはNotNull AFAIKに従わないので、<:<メソッドよりも少し一般的ではありませんが、そうでなければ、あなたが望むであろうことを正確に行います。

8
Rex Kerr

Scalastyleがnullでテスト内のオブジェクトを初期化するときにnullを使用しないように指示したため、この質問に出会いました。

Scalastyleを満たすタイプを変更しない私のソリューション:

var a: MyObject = (None: Option[MyObject]).orNull
0
Guenter