Question:
Judging by the names, all types mean the same thing. In what cases in scala
should you use: Nothing
, Null
, Nil
and None
, how do they differ?
Answer:
Well written here . I will add something, I will summarize something.
The Nothing type is the lowest type. This means that variables with this type can be assigned to absolutely any other type.
Example 1:
def isTen(number: Int): Boolean =
if (10 == number) true
else throw new Exception("Number is not ten")
true
is of type Boolean
, throwing an exception is of type Nothing
, and since Nothing
inherits Boolean
in the type hierarchy, the result is Boolean
.
Example 2:
def genericIsTen[T](value: T): T =
if (10 == value) value
else throw new Exception("Generic is not ten")
Since Nothing
is the lowest type, it means that in the type hierarchy the heir of any type – instead of Boolean
can be a generic.
Example 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
Similarly to the examples above, an object with the Box[Nothing]
type is easily assigned to the Box[Int]
type (due to the covariance , i.e. that trait's plus sign).
The conclusion, as you can see, the type Nothing
is used when you need the type to be accepted by another type. "Frayed" by another type.
The Null type is almost the lowest type. In the type hierarchy, it is the heir of all objects, but not the heir of all primitives. This means that it will work for objects in the same way as Nothing.
isTen(null) // НЕ будет работать так как функция хочет примитив
genericIsTen((null) // будет работать
boxedIsTen(null) // НЕ будет работать так как функция хочет Int
Nil is not a type, it's a Nil
object. The type of this object is Nil.type
. The Nil
object is one of two descendants of the List
class and is used where an empty list of type List
is needed. Well, since it is the heir of List
, all its methods are available to it.
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 is not a type either, but a None
object. The type of this object is None.type
. The None
object is one of two descendants of the Option
class and is used as an empty 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