2014-09-11 5 views
7

Nach dieser Antwort https://stackoverflow.com/a/8001065/1586965 wir können dies in Scala tun:Was sind die Anwendungsfälle der Ignorierten Variablen-Syntax in Scala?

val _ = 5 

Jetzt verstehe ich den Punkt ignoriert Parameter in Lambda-Ausdrücke, aber ich kann nicht wirklich Beispiele vorstellen, wo ich jemals eine Variable deklarieren wollen würde, dass durch Definition, die ich nicht referenzieren kann. Das einzige Beispiel, an das ich denken kann, ist die Tatsache, dass implizite Werte, z.

implicit val _: MyNumeric = ... 
... 
class A[T : MyNumeric] { 
... 

Ist dies der einzige Anwendungsfall? Fehle ich etwas?

Wenn es der einzige Anwendungsfall ist, sollte nicht der Compiler/IDE eine Warnung/Hinweis geben, wenn die valnicht implizit als es völlig sinnlos ist?

Klärungs

durch variable/Mittelwert I a einzige einen, nicht eine, die einen Teil einer Extraktions Erklärung.

+0

Ihr klären sagt, dass Sie bedeuten nicht, Muster, aber das Argument am Ende dieses Ticket ist, dass es eine ist Muster. https://issues.scala-lang.org/browse/SI-7691 Ich denke, es ist ein Name, kein Muster, und würde spezielle Spezifikation erfordern; aber immer noch interessant. –

+0

Jemand antwortete mit For-Comps wie hier (für unkonstruiertes Beispiel): https://github.com/scala/scala/blob/v2.11.2/src/library/scala/Responder.scala # L44 und ähnlich 'für (i <- g; _ = v)' –

Antwort

8

Es verwendet einen Wert.

$ scala -Ywarn-value-discard 
Welcome to Scala version 2.11.2 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_11). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> def f() = { println("I ran.") ; 42 } 
f:()Int 

scala> def g(): Unit = { f() } 
<console>:8: warning: discarded non-Unit value 
     def g(): Unit = { f() } 
         ^
g:()Unit 

scala> def g(): Unit = { val _ = f() } 
g:()Unit 

scala> g 
I ran. 

scala> 

Zur Verifizierung warnt es auch nicht unter -Ywarn-unused.

+2

Zuweisungen werden in Scala immer zu 'Einheit' ausgewertet. Sie erhalten das exakt gleiche Ergebnis, wenn Sie 'val foo' anstelle von' val _' verwenden, nein? –

+2

@ JörgWMittag Der Block erhält immer noch den Einheitswert am Ende als Ergebnisausdruck, aber mit der Zuweisung verwerfen Sie keinen Wert; Mit Unterstreichung haben Sie Ihr Gehirn nicht dazu gebracht, einen Identifikator zu erfinden. Eine Strecke, um dies einen Anwendungsfall zu nennen. –

6

Der andere Anwendungsfall (das ich mir vorstellen kann) mit Extraktion bezogen (und wird unter „Wildcard-Muster“ in the linked answer rief):

val getCartesianPoint =() => (1, 2, 3) 
// We don't care about the z axis, so we assign it to _ 
val (x, y, _) = getCartesianPoint() 

val regex = "(.*?)|(.*?)|?.*".r 
// Really, any unapply or unapplySeq example will do 
val regex(_, secondValue) = "some|delimited|value|set" 
+0

Korrekt, aber akzeptiere die andere Antwort, da sie näher zu meiner Frage passt. Ich werde meiner Frage eine Klarstellung hinzufügen. – samthebest

15

Ich glaube nicht, dass dies ein Feature überhaupt ist. In jedem Fall ist es nicht eine "ignorierte Variable". Mit dem ich meine, dass, wenn val _ = 5 wirklich einen unbenannten Wert eingeführt wurde, dann könnten Sie so viele wie Sie wollen in dem gleichen einzelnen Bereich deklarieren. Nicht so:

scala> object Test { 
    | val _ = 5 
    | val _ = 7 
    | } 
<console>:9: error: _ is already defined as value _ 
     val _ = 7 
     ^

Von der Fehlermeldung scheint es klar, dass wirklich das, was passiert ist, dass der Wert tatsächlich _ gestattet (die ich eine Marotte des Compilers nennen würde, die behoben werden sollen). Wir können dies überprüfen:

scala> object Test { 
    | val _ = 5 
    | def test() { println(`_`) } // This compiles fine 
    | } 
defined object Test 

scala> Test.test() 
5 

Was die mögliche Verwendung eines Wertes zu verhindern Wegwerfen Warnung (wie in som-snytt Antwort gezeigt), I'much bevorzugen eine explizite Unit einfach zurück. Das sieht weniger verworren und noch kürzer:

def g(): Unit = { f();() } 

im Gegensatz zu:

def g(): Unit = { val _ = f() }  
+0

Hmm, ja, es ist eine Eigenart, kein Feature, aber ich mag es und bevorzuge die 'val _ = f()' als einzige Zeile. Ich würde niemals zwei Linien auf 1 setzen, indem ich Halbkegel benutze. – samthebest

+0

https://github.com/typelevel/scala/issues/9 und ähnlich. –

+0

Ich bevorzuge diese Antwort viel lieber –

Verwandte Themen