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?
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
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)
}
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ę.
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
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