Скажем, у меня есть экземпляр MyObject
, который не инициализирован:
var a:MyObject = null
- это правильный способ инициализировать его нулевым?
Скажем, у меня есть экземпляр MyObject
, который не инициализирован:
var a:MyObject = null
- это правильный способ инициализировать его нулевым?
Используйте null
в качестве последнего средства. Как уже упоминалось, Option
заменяет большинство применений null. Если вы используете null
для реализации отложенной инициализации поля с некоторым дорогостоящим вычислением, вы должны использовать lazy val
.
Тем не менее, Scala поддерживает null
. Я лично использую его в сочетании с Spring Injection of Dependency.
Ваш код отлично работает. Однако я предлагаю вам использовать 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
Использование var t: T= null
является компиляционной ошибкой, если T неограничен:
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
Канонический ответ не использует null. Вместо этого используйте тип опции:
var a = None : Option[MyObject]
Если вы хотите установить его:
a = Some(foo)
И когда вы хотите прочитать из него, проверьте на None:
a match {
case None => Console.println("not here")
case Some(value) => Console.println("got: "+value)
}
Как уже упоминалось Дэвидом и ретроном, рекомендуется использовать Option
в большинстве случаев, поскольку Option
делает более очевидным, что вам приходится обрабатывать ситуацию без результата. Однако для возврата Some(x)
требуется создание объекта, а вызов .get
или .getOrElse
может быть дороже, чем if-statement. Таким образом, при использовании высокопроизводительного кода использование Option
не всегда является лучшей стратегией (особенно в коде поиска, где вы можете найти значение очень много раз и не хотите, соответственно, много создания объектов). Опять же, если вы делаете что-то вроде возврата текста всей веб-страницы (которая может отсутствовать), нет причин не использовать параметр.
Кроме того, просто чтобы добавить к методу retron для дженериков с null
, вы можете сделать это в полном объеме, если вы действительно имеете в виду, что это должно быть null
:
class A[T >: Null] { var t: T = null }
и это работает в 2.7 и 2.8. Это немного менее общий, чем метод <:<
, потому что он не подчиняется NotNull
AFAIK, но в противном случае делает именно то, что вы надеялись бы сделать.
Я столкнулся с этим вопросом, так как scalastyle сказал мне не использовать null при инициализации объекта в моем тесте с помощью null
.
Мое решение без изменения какого-либо типа, удовлетворяющего scalastyle:
var a: MyObject = (None: Option[MyObject]).orNull