Страницы

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

вторник, 10 декабря 2019 г.

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

#scala


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


Ответы

Ответ 1



Хорошо расписано тут. Кое-что добавлю, кое-что подрезюмирую. Тип 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

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

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