Ich habe mir die Liste der auf scala-lang.org durchgeführten Umfragen angesehen und eine merkwürdige Frage festgestellt: " Können Sie alle Verwendungszwecke von" _ "nennen? ". Können Sie? Wenn ja, bitte hier. Erklärende Beispiele werden geschätzt.
540
Antworten:
Die, an die ich denken kann, sind
Existenzielle Typen
Höher sortierte Typparameter
Ignorierte Variablen
Ignorierte Parameter
Ignorierte Namen von Selbsttypen
Platzhaltermuster
Platzhaltermuster in Interpolationen
Sequenz-Platzhalter in Mustern
Platzhalterimporte
Importe verstecken
Briefe an Operatoren verbinden
Zuweisungsoperatoren
Platzhaltersyntax
Methodenwerte
Konvertieren von Call-by-Name-Parametern in Funktionen
Standardinitialisierer
Es kann andere geben, die ich vergessen habe!
Beispiel zeigt warum
foo(_)
undfoo _
sind unterschiedlich:Dieses Beispiel stammt von 0__ :
Stellt im ersten Fall
process _
eine Methode dar; Scala verwendet die polymorphe Methode und versucht, sie durch Ausfüllen des Typparameters monomorph zu machen, stellt jedoch fest, dass kein Typ ausgefülltA
werden kann, der den Typ ergibt(_ => Unit) => ?
(Existential_
ist kein Typ).Im zweiten Fall
process(_)
ist ein Lambda; Wenn Sie ein Lambda ohne expliziten Argumenttyp schreibenforeach
,_ => Unit
leitet Scala den Typ aus dem erwarteten Argument ab und ist ein Typ (während dies einfach_
nicht der Fall ist), sodass er ersetzt und abgeleitet werden kann.Dies ist wahrscheinlich das schwierigste Problem in Scala, dem ich je begegnet bin.
Beachten Sie, dass dieses Beispiel in 2.13 kompiliert wird. Ignorieren Sie es, als wäre es dem Unterstrich zugewiesen worden.
quelle
val x: Any = _
println _
undprintln(_)
sind anders. Sie können dies zum Beispiel daran sehen, dass sie existenzielle und polymorphe Typen etwas unterschiedlich behandeln. Ich werde gleich ein Beispiel finden.Aus (meinem Eintrag) in den FAQ , deren Vollständigkeit ich sicherlich nicht garantieren kann (ich habe erst vor zwei Tagen zwei Einträge hinzugefügt):
Dies ist auch Teil dieser Frage .
quelle
var i: Int = _
val (a, _) = (1, 2)
for (_ <- 1 to 10) doIt()
def f: T; def f_=(t: T)
Kombination zum Erstellen eines veränderlichen f-Mitglieds._
bei Methodennamen wird geschummelt. Aber gut, ok. Ich hoffe nur, dass jemand anderes die FAQ aktualisiert ... :-)Eine ausgezeichnete Erklärung für die Verwendung des Unterstrichs ist Scala _ [Unterstrich] Magie .
Beispiele:
In Scala verhält es sich beim Importieren von Paketen
_
ähnlich wie*
in Java.In Scala werden ein Getter und ein Setter implizit für alle nicht privaten Variablen in einem Objekt definiert. Der Getter-Name entspricht dem Variablennamen und
_=
wird für den Setter-Namen hinzugefügt.Verwendungszweck:
Wenn Sie versuchen, einer neuen Variablen eine Funktion zuzuweisen, wird die Funktion aufgerufen und das Ergebnis der Variablen zugewiesen. Diese Verwirrung tritt aufgrund der optionalen geschweiften Klammern für den Methodenaufruf auf. Wir sollten _ nach dem Funktionsnamen verwenden, um ihn einer anderen Variablen zuzuweisen.
quelle
List(1,2,3,4,5).foreach(print(_))
es viel besser lesbar, nur zu tunList(1,2,3,4,5).foreach(print)
, Sie brauchen nicht einmal wirklich den Unterstrich, aber ich denke, das ist nur eine Frage des StilsEs gibt eine Verwendung, die ich sehen kann. Jeder hier scheint vergessen zu haben, sie aufzulisten ...
Anstatt dies zu tun:
Sie können dies einfach tun:
quelle
n => n
Hier sind einige weitere Beispiele, wo
_
verwendet wird:In allen obigen Beispielen repräsentiert ein Unterstrich ein Element in der Liste (zum Reduzieren repräsentiert der erste Unterstrich den Akkumulator).
quelle
Neben den von JAiro erwähnten Verwendungen gefällt mir diese:
Wenn jemand alle Verbindungseigenschaften benötigt, kann er Folgendes tun:
Wenn Sie nur einen Host und einen Port benötigen, können Sie Folgendes tun:
quelle
Es gibt ein spezielles Beispiel für die Verwendung von "_":
kann gleich sein:
Wenn Sie in einigen Szenarien "_" anwenden, wird automatisch in "(x $ n) => x $ n" konvertiert.
quelle