Czy jest to właściwy sposób inicjalizacji odwołań null w Scali?

Załóżmy, że mam instancję MyObject, która nie jest inicjalizowana:

var a:MyObject = null

Czy to jest właściwy sposób, aby zainicjować go do null?

 48
Author: Geo, 2010-03-14

4 answers

Alternatywy

Użyj null w ostateczności. Jak już wspomniano, Option zastępuje większość zastosowań null. Jeśli używasz null do implementacji odroczonej inicjalizacji pola z kosztownymi obliczeniami, powinieneś użyć lazy val.

Kanoniczna inicjalizacja do null

To powiedziawszy, Scala obsługuje null. Osobiście używam go w połączeniu z Spring Dependency Injection.

Twój kod jest całkowicie poprawny. Proponuję jednak użyć var t: T = _ do initialize t to jego wartość domyślna. Jeśli {[10] } jest prymitywny, otrzymujesz domyślną wartość specyficzną dla danego typu. W przeciwnym razie otrzymasz null.

Nie tylko jest to bardziej zwięzłe, ale jest konieczne, gdy nie wiesz z góry, co T będzie: {]}

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

Zaawansowane

Użycie var t: T= null jest błędem kompilacji, jeśli T jest unbounded:

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 }

Możesz dodać parametr niejawny jako dowód, że T jest nullable -- Podtyp AnyRef a nie Podtyp NotNull to nie jest w pełni pieczone , nawet w Scali 2.8, więc na razie potraktuj to jako ciekawostkę.

scala> class A[T](implicit ev: Null <:< T) { var t: T = null }           
defined class A
 57
Author: retronym,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-02 17:04:49

Kanoniczna odpowiedź to nie używaj null . Zamiast tego użyj typu opcji:

var a = None : Option[MyObject]

Gdy chcesz go ustawić:

a = Some(foo)

A jak chcesz z niego czytać, testuj na brak:

a match {
  case None => Console.println("not here")
  case Some(value) => Console.println("got: "+value)
}
 29
Author: David Crawshaw,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-03-13 21:48:25

Jak już wspominali David i retronym, dobrym pomysłem jest użycie Option w większości przypadków, ponieważ Option sprawia, że bardziej oczywiste jest, że musisz poradzić sobie z sytuacją bez rezultatu. Jednak zwrócenie Some(x) wymaga utworzenia obiektu, a wywołanie .get lub .getOrElse może być droższe niż polecenie if. Tak więc w kodzie o wysokiej wydajności użycie Option nie zawsze jest najlepszą strategią (szczególnie w kodzie collection-lookup, gdzie można wyszukać wartość bardzo wiele razy i nie chcieć odpowiednio wiele obiektów). Z drugiej strony, jeśli robisz coś takiego jak zwracanie tekstu całej strony internetowej( która może nie istnieć), nie ma powodu Nie, aby użyć opcji.

Ponadto, aby dodać do retronimu punkt na generyki z null, możesz to zrobić w pełni wypiekany sposób, jeśli naprawdę chcesz to być null: {]}

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

I to działa w 2.7 i 2.8. Jest trochę mniej ogólna niż metoda <:<, ponieważ nie spełnia NotNull AFAIK, ale poza tym dokładnie to, na co masz nadzieję.

 8
Author: Rex Kerr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-07 16:40:35

Natknąłem się na to pytanie, ponieważ scalastyle powiedział mi, aby nie używać null podczas inicjalizacji obiektu w moim teście za pomocą null.

Moje rozwiązanie bez zmiany typu spełniającego skalastyle:

var a: MyObject = (None: Option[MyObject]).orNull
 0
Author: Guenter,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-02-15 13:52:04