Je viens de lire: http://oldfashionedsoftware.com/2008/08/20/a-post-about-nothing/
Autant que je sache, Null
est un trait et son seul exemple est null
.
Lorsqu'une méthode prend un argument Null, nous pouvons uniquement lui passer directement une référence Null
ou null
, mais pas une autre référence, même si elle est nulle (nullString: String = null
par exemple).
Je me demande simplement dans quels cas utiliser ce trait Null
pourrait être utile ..__ Il y a aussi le trait Nothing pour lequel je ne vois pas vraiment plus d'exemples.
Je ne comprends pas vraiment non plus quelle est la différence entre utiliser Nothing et Unit en tant que type de retour, puisque les deux ne renvoient aucun résultat. Comment savoir lequel utiliser lorsque j'ai une méthode qui effectue la journalisation, par exemple?
Avez-vous des usages de Unit/Null/Nothing comme autre chose qu'un type de retour?
Vous utilisez uniquement Nothing si la méthode ne retourne jamais (ce qui signifie qu'elle ne peut pas se terminer normalement en renvoyant, elle pourrait générer une exception). Rien n'est jamais instancié et existe pour le système de types (pour citer James Iry: "La raison pour laquelle Scala a un type de fond est liée à sa capacité à exprimer la variance des paramètres de type." ). De l'article que vous avez lié à:
Une autre utilisation de Nothing est en tant que type de retour pour des méthodes qui n'ont jamais revenir. C'est logique si vous y réfléchissez. Si une méthode retourne le type est Nothing, et il n’existe absolument aucune instance de Nothing, alors une telle méthode ne doit jamais revenir.
Votre méthode de journalisation renverrait l'unité. Il existe une valeur Unité qui peut donc être renvoyée. A partir de la documentation API :
L'unité est un sous-type de scala.AnyVal. Il n'y a qu'une seule valeur de type Unit, (), et il n'est représenté par aucun objet dans le sous-jacent système d'exécution. Une méthode avec le type de retour Unit est analogue à Java méthode qui est déclarée nulle.
L'article que vous citez peut être trompeur. Le type Null
existe pour la compatibilité avec la machine virtuelle Java , et Java en particulier.
Nous devons considérer que Scala :
null
références pour accéder, par exemple, aux bibliothèques Java et au codeil devient donc nécessaire de définir un type pour la valeur null
, qui est le trait Null
et dont null
est l'unique instance.
Il n'y a rien de particulièrement utile dans le type Null
sauf si vous êtes le système de types ou que vous développez sur le compilateur. En particulier, je ne vois aucune raison valable de définir un paramètre de type Null
pour une méthode, car vous ne pouvez rien transmettre d'autre que null
Avez-vous des usages de Unit/Null/Nothing comme autre chose qu'un type de retour?
Unit
peut être utilisé comme ceci:
def execute(code: => Unit):Unit = {
// do something before
code
// do something after
}
Cela vous permet de transmettre un bloc de code arbitraire à exécuter.
Null
peut être utilisé comme type de bas pour toute valeur pouvant être nullable. Voici un exemple:
implicit def zeroNull[B >: Null] =
new Zero[B] { def apply = null }
Nothing
est utilisé dans la définition de None
object None extends Option[Nothing]
Cela vous permet d'affecter une None
à n'importe quel type de Option
car Nothing
'étend' tout.
val x:Option[String] = None
Je n'ai jamais réellement utilisé le type Null
, mais vous utilisez Unit
, où vous utiliseriez void
sur Java. Nothing
est un type spécial, car, comme Nathan l'a déjà mentionné, il ne peut y avoir d'instance de Nothing
. Nothing
est un type dit de bas, ce qui signifie qu'il s'agit d'un sous-type de tout autre type. Ceci (et le paramètre de type contravariant) explique pourquoi vous pouvez ajouter n'importe quelle valeur à Nil
- qui est un List[Nothing]
- et la liste sera alors de ce type d'éléments. None
également si de type Option[Nothing]
. Toute tentative d'accès aux valeurs à l'intérieur d'un tel conteneur lève une exception, car c'est le seul moyen valide de retourner à partir d'une méthode de type Nothing
.
si vous utilisez Nothing
, il n'y a rien à faire (incluez la console d'impression) si vous faites quelque chose, utilisez le type de sortie Unit
object Run extends App {
//def sayHello(): Nothing = println("hello?")
def sayHello(): Unit = println("hello?")
sayHello()
}
... alors comment utiliser Nothing
?
trait Option[E]
case class Some[E](value: E) extends Option[E]
case object None extends Option[Nothing]
Rien est souvent utilisé implicitement. Dans le code ci-dessous, val b: Boolean =
if (1 > 2) false
else throw new RuntimeException("error")
La clause else est de type Nothing , qui est une sous-classe de Boolean (ainsi que tout autre AnyVal). Ainsi, toute l’affectation est valable pour le compilateur, bien que la clause else ne retourne rien.
Voici un exemple de Nothing
à partir de scala.predef
:
def ??? : Nothing = throw new NotImplementedError
Si vous n'êtes pas familier (et que les moteurs de recherche ne peuvent pas y effectuer une recherche), ???
est la fonction d'espace réservé de Scala pour tout ce qui n'a pas encore été implémenté. Tout comme la variable TODO
de Kotlin.
Vous pouvez utiliser le même truc lors de la création d'objets fantaisie: remplacez les méthodes inutilisées par une méthode notUsed
personnalisée. L'avantage de ne pas utiliser ???
est que vous ne recevrez pas d'avertissement de compilation pour des choses que vous n'avez jamais l'intention de mettre en œuvre.
En termes de théorie des catégories, Nothing est un objet initial et Unit est un objet terminal.
https://en.wikipedia.org/wiki/Initial_and_terminal_objects
Les objets initiaux sont également appelés coterminal ou universal et les objets terminaux sont également appelés final.
Si un objet est à la fois initial et terminal, il est appelé objet zero ou null.