Скажем, у меня есть a MyObject
экземпляр, который не инициализируется:
var a:MyObject = null
действительно ли это - надлежащий способ инициализировать его к пустому указателю?
В крайнем случае используйте null
. Как уже упоминалось, Опция
заменяет большинство случаев использования 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
Использование 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)
}
Как уже отметили Дэвид и retronym, в большинстве случаев целесообразно использовать Option
, поскольку Option
делает более очевидным, что вы должны обработать ситуацию без результата. Однако возврат Some(x)
требует создания объекта, а вызов .get
или .getOrElse
может быть дороже, чем if-выражение. Таким образом, в высокопроизводительном коде использование Option
не всегда является лучшей стратегией (особенно в коде просмотра коллекции, где вы можете искать значение очень много раз и не хотите, чтобы было создано соответствующее количество объектов). С другой стороны, если вы делаете что-то вроде возврата текста всей веб-страницы (которой может не существовать), нет причин не использовать Option.
Также, чтобы добавить к замечанию retronym о дженериках с null
, вы можете сделать это в полной мере, если вы действительно хотите, чтобы это было null
:
class A[T >: Null] { var t: T = null }
и это работает в 2.7 и 2.8. Это немного менее общий метод, чем <:<
, потому что он не подчиняется NotNull
AFAIK, но в остальном он делает именно то, на что вы надеетесь.