Frage Nutzungen von Null / Nichts / Einheit in Scala


Ich habe gerade gelesen: http://oldfashionedsoftware.com/2008/08/20/a-post-about-nothing/

So weit ich das verstehe, Null ist ein Merkmal und seine einzige Instanz ist null.

Wenn eine Methode ein Argument Null annimmt, können wir sie nur übergeben a Null Referenz oder null direkt, aber keine andere Referenz, auch wenn es null ist (nullString: String = null beispielsweise).

Ich frage mich nur, in welchen Fällen ich das benutze Null Merkmal könnte nützlich sein. Es gibt auch das Merkmal Nothing, für das ich keine Beispiele mehr sehe.


Ich verstehe auch nicht wirklich, was ist der Unterschied zwischen der Verwendung von Nothing und Unit als Rückgabetyp, da beide kein Ergebnis zurückgibt, wie zu wissen, welche zu verwenden, wenn ich eine Methode zum Beispiel Protokollierung ausführen?


Haben Sie Verwendungen von Unit / Null / Nothing als etwas anderes als einen Rückgabetyp?


76
2018-04-23 15:34


Ursprung


Antworten:


Sie verwenden Nothing nur dann, wenn die Methode nie zurückkehrt (dh sie kann nicht normal abgeschlossen werden, da sie eine Ausnahme auslösen kann). Nichts wird niemals instanziiert und ist zum Vorteil des Typsystems (um James Iry zu zitieren): "Der Grund, warum Scala einen Bottom-Typ hat, hängt mit seiner Fähigkeit zusammen, Varianz in Typparametern auszudrücken."). Aus dem Artikel, mit dem Sie verknüpft sind:

Eine andere Verwendung von Nothing ist ein Rückgabetyp für Methoden, die niemals funktionieren   Rückkehr. Es macht Sinn, wenn Sie darüber nachdenken. Wenn eine Methode zurückgegeben wird   Typ ist Nichts, und es gibt absolut keine Instanz von Nichts,   dann darf eine solche Methode niemals zurückkehren.

Ihre Protokollierungsmethode würde Unit zurückgeben. Es gibt eine Werteinheit, so dass sie tatsächlich zurückgegeben werden kann. Von dem API-Dokumente:

Unit ist ein Untertyp von scala.AnyVal. Es gibt nur einen Wert vom Typ   Unit, (), und es wird von keinem Objekt im zugrunde liegenden Objekt dargestellt   Laufzeitsystem. Eine Methode mit dem Rückgabetyp Unit ist analog zu Java   Methode, die für ungültig erklärt wird.


65
2018-04-23 15:40



Der Artikel, den Sie angeben, kann irreführend sein. Das Null Typ ist da für die Kompatibilität mit dem Java virtuelle Maschineund insbesondere Java.

Das müssen wir bedenken Scala:

  • ist vollständig objektorientiert: Jeder Wert ist ein Objekt
  • ist stark typisiert: Jeder Wert muss einen Typ haben
  • muss behandelt werden null Referenzen zum Zugriff, zum Beispiel Java-Bibliotheken und Code

Daher wird es notwendig, einen Typ für die null Wert, der ist der Null Merkmal, und hat null als einzige Instanz.

Es gibt nichts besonders nützlich in der Null Geben Sie ein, es sei denn, Sie sind das Typsystem oder Sie entwickeln den Compiler. Insbesondere sehe ich keinen vernünftigen Grund, ein zu definieren Null Geben Sie den Parameter für eine Methode ein, da Sie nichts übergeben können null


16
2018-04-23 16:40



Hast du Gebräuche von Einheit / Null / Nichts als etwas anderes als a   Rückgabetyp?


Unit kann so verwendet werden:

def execute(code: => Unit):Unit = {
  // do something before
  code
  // do something after
}

Auf diese Weise können Sie einen beliebigen Codeblock übergeben, der ausgeführt werden soll.


Null kann als unterer Typ für alle Werte verwendet werden, die Nullwerte enthalten können. Ein Beispiel ist das:

implicit def zeroNull[B >: Null] =
    new Zero[B] { def apply = null }

Nothingwird in der Definition von verwendet None

object None extends Option[Nothing]

Damit können Sie a zuweisen None zu irgendeiner Art von Option weil Nothing 'erweitert' alles.

val x:Option[String] = None

14
2018-04-23 16:40



Ich habe das nie benutzt Null Geben Sie, aber Sie verwenden Unitwo würdest du Java benutzen void. Nothing ist eine besondere Art, denn wie Nathan bereits erwähnt hat, kann es keine Instanz geben Nothing. Nothing ist ein sogenannter Bottom-Typ, was bedeutet, dass es sich um einen Subtyp eines anderen Typs handelt. Dies (und der kontravariante Typparameter) ist der Grund dafür, dass Sie jedem Wert einen Präfix voranstellen können Nil - die ein List[Nothing] - und die Liste wird dann von diesem Elementtyp sein. None auch wenn vom Typ Option[Nothing]. Jeder Versuch, auf die Werte innerhalb eines solchen Containers zuzugreifen, löst eine Ausnahme aus, da dies der einzig gültige Weg ist, von einer Methode des Typs zurückzukehren Nothing.


5
2018-04-23 15:50



wenn du benutzt Nothing, es gibt keine Dinge zu tun (einschließlich Print-Konsole) Wenn Sie etwas tun, verwenden Sie den Ausgabetyp Unit

object Run extends App {
  //def sayHello(): Nothing = println("hello?")
  def sayHello(): Unit = println("hello?")
  sayHello()
}

... dann wie zu benutzen Nothing?

trait Option[E]
case class Some[E](value: E) extends Option[E]
case object None extends Option[Nothing]

5
2018-04-07 04:35



Nichts wird oft implizit verwendet. Im folgenden Code      val b: Boolean = if (1 > 2) false else throw new RuntimeException("error") das sonst Klausel ist vom Typ NichtsDies ist eine Unterklasse von Boolean (sowie jede andere AnyVal). Somit ist die gesamte Zuordnung für den Compiler gültig, obwohl der sonst Klausel gibt wirklich nichts zurück.


2
2018-06-29 23:34



Hier ist ein Beispiel von Nothing von scala.predef:

  def ??? : Nothing = throw new NotImplementedError

Für den Fall, dass Sie nicht vertraut sind (und Suchmaschinen können nicht darauf suchen) ??? ist Scalas Platzhalterfunktion für alles, was noch nicht implementiert wurde. Genau wie Kotlin TODO.

Sie können den gleichen Trick beim Erstellen von Mock-Objekten verwenden: Überschreiben Sie nicht verwendete Methoden mit einer benutzerdefinierten Methode notUsed Methode. Der Vorteil, nicht zu verwenden ??? Das ist, dass Sie keine Warnungen für Dinge kompilieren werden, die Sie nie umsetzen möchten.


0
2018-06-06 22:09