Страницы

Поиск по вопросам

суббота, 13 октября 2018 г.

Зачем нужны Nothing, Null, Nil и None

Судя по именам все типы означают одно и тоже. В каких случаях в scala нужно применять: Nothing, Null, Nil и None, чем они отличаются?


Ответ

Хорошо расписано тут. Кое-что добавлю, кое-что подрезюмирую.
Тип Nothing - это самый нижний тип. Это значит что переменные с таким типом можно присвоить к абсолютно любому другому типу.
Пример 1:
def isTen(number: Int): Boolean = if (10 == number) true else throw new Exception("Number is not ten")
true имеет тип Boolean, кидание исключения имеет тип Nothing и так как Nothing в иерархии типов наследник Boolean, то в результате получается тип Boolean
Пример 2:
def genericIsTen[T](value: T): T = if (10 == value) value else throw new Exception("Generic is not ten")
Так как Nothing самый нижний тип, значит в иерархии типов наследник любого типа - вместо Boolean может быть и дженерик.
Пример 3:
trait Box[+T]
case class Full[T](value: T) extends Box[T] object Empty extends Box[Nothing]
def boxedIsTen(value: Int): Box[Int] = if (10 == value) Full(value) else Empty
Аналогично примерам выше объект с типом Box[Nothing] спокойно присваивается к типу Box[Int] (благодаря ковариантности, т.е. тому плюсику у трейта).
Вывод, как видишь тип Nothing используется тогда, когда нужно чтоб тип был принят другим типом. "Перетёрт" другим типом.
Тип Null - это почти самый нижний тип. В иерархии типов - он наследник всех объектов, но не наследник всех примитивов. А значит он будет работать для объектов точно также как и Nothing.
isTen(null) // НЕ будет работать так как функция хочет примитив genericIsTen((null) // будет работать boxedIsTen(null) // НЕ будет работать так как функция хочет Int
Nil - это не тип, это объект Nil. Тип у этого объекта Nil.type. Объект Nil - один из двух наследников класса List и используется он там, где нужен пустой список типа List. Ну и так как он наследник List-а, у него доступны все его методы.
sealed abstract class List[+A] { /* ... */ }
case object Nil extends List[Nothing] { /* ... */ } final case class ::[B]( /* ... */ ) extends List[B] { /* ... */}
def listIsTen(number: Int): List[Int] = if (10 == number) List(number) else Nil
None - это тоже не тип, а объект None. Тип у этого объекта None.type. Объект None - один из двух наследников класса Option и используется как пустой вариант Option.
sealed abstract class Option[+A]
case object None extends Option[Nothing] { /* ... */ } final case class Some[+A](x: A) extends Option[A] { /* ... */ }
def optionIsTen(number: Int): Option[Int] = if (10 == number) Some(number) else None

Комментариев нет:

Отправить комментарий