2014-09-11 53 views
7

根據這個答案https://stackoverflow.com/a/8001065/1586965我們可以在Scala中做到這一點:Scala中忽略變量語法的用例是什麼?

val _ = 5 

現在我明白了在lambda表達式中被忽略的參數點,但我真的不能想象的例子,我會永遠要聲明一個變量,它由定義我不能參考。我能想到的唯一例子是關於命名隱含的值的懶惰,例如,

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

這是唯一的用例嗎?我錯過了什麼嗎?

如果它是唯一的用例,那麼當val而不是暗示它是完全沒有意義的時,編譯器/ IDE是否應該給出警告/提示?

澄清

通過變量/值我的意思是一個單一一個,而不是一個是提取聲明的一部分。

+0

你澄清說,你不是說模式,但在這個票結束的說法是,它是一個模式。 https://issues.scala-lang.org/browse/SI-7691我認爲這是一個名字,而不是一個模式,需要特殊的規範;但仍然很有趣。 – 2014-09-11 13:42:32

+0

有人回答與-譜曲喜歡這裏(對於未計劃爲例):https://github.com/scala/scala/blob/v2.11.2/src/library/scala/Responder。scala#L44和類似'for(i <-g; _ = v)' – 2014-09-11 13:51:58

回答

8

它使用的值。

$ 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> 

要驗證,它也不會在-Ywarn-unused下發出警告。

+2

賦值總是在Scala中評估爲「Unit」。如果您使用'val foo'而不是'val _',否則會得到完全相同的結果? – 2014-09-11 10:54:29

+2

@JörgWMittag該塊仍然在結尾處插入作爲結果表達式的單位值,但通過賦值,您不會丟棄值;用下劃線表示,你還沒有絞盡腦汁發明一個標識符。一段時間稱之爲用例。 – 2014-09-11 13:24:42

6

其他使用情況下(即我能想到的)有關提取(和下the linked answer「通配符模式」被稱爲出來):

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

正確,但接受另一個答案,因爲它更符合我的問題。我要添加一個澄清我的問題。 – samthebest 2014-09-11 05:21:12

15

我不認爲這是一個功能都沒有。無論如何,它是而不是一個「被忽略的變量」。 我的意思是說,如果val _ = 5確實引入了一個未命名的值,那麼您可以在同一個單一範圍內聲明儘可能多的數。 並非如此:

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

從錯誤信息似乎很清楚,到底發生了什麼是價值實際上是命名爲_ (我會打電話給那應該是固定的編譯器的怪癖)。我們可以驗證這一點:

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

scala> Test.test() 
5 

至於可能使用防止值丟棄警示(如圖SOM-snytt的答案)中,I'much喜歡簡單地返回一個明確的Unit。 這看起來不太令人費解和更短:

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

,而不是:

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

嗯,是的出現了它的一個怪癖,而不是一個功能,但我喜歡它,並且寧願'val _ = f()'作爲它唯一的一行。我永遠不會把兩行用半角來放到1上。 – samthebest 2014-09-11 09:44:15

+0

https://github.com/typelevel/scala/issues/9和類似的。 – 2015-06-10 08:04:54

+0

我更喜歡這個答案 – 2016-05-16 05:21:35