为什么在REPL中这个表达式失败:
List("a", "b").foreach { System.out.println(s"Valor=$_") }
出现此错误:
<console>:1: error: unclosed string literal
而另一个成功:
List("a", "b").foreach { x => System.out.println(s"Valor=$x") }
我怀疑&#34; _&#34;变量不受支持。
这是一个错误还是设计?
答案 0 :(得分:6)
您显示的错误消息与我在Scala 2.11.1中显示的错误消息不同:
scala> List("a", "b").foreach { System.out.println(s"Valor=$_") }
<console>:1: error: error in interpolated string: identifier or block expected
List("a", "b").foreach { System.out.println(s"Valor=$_") }
^
<console>:1: error: ')' expected but '}' found.
List("a", "b").foreach { System.out.println(s"Valor=$_") }
^
现在回答你的问题。 SIP-11,它定义了Scala的字符串插值,不允许以除字母之外的任何内容开头的标识符。这可能有点过于复杂,但如果您考虑对插值字符串的去除,则对特殊的_
标识符有意义。
你的例子:
List("a", "b").foreach { System.out.println(s"Valor=$_") }
本来会对此感到害怕:
List("a", "b").foreach { System.out.println(StringContext("Valor=", "").s(_)) }
这清楚地表明_
无法与传递给foreach
的函数的参数相关联。这是尝试执行desugaring时报告的错误消息:
scala> List("a", "b").foreach { System.out.println(StringContext("Valor=", "").s(_)) }
<console>:8: error: type mismatch;
found : Unit
required: String => ?
List("a", "b").foreach { System.out.println(StringContext("Valor=", "").s(_)) }
简而言之,这种情况的发生是因为脱毒的方式。
答案 1 :(得分:0)
该错误具有误导性,但这里的主要问题是您将匿名函数传递给println:
列表(&#34; a&#34;,&#34; b&#34;)。foreach {System.out.println(s&#34; Valor = $ _&#34;)}
相当于
列表(&#34; a&#34;,&#34; b&#34;)。foreach {System.out.println(x =&gt; s&#34; Valor = $ x&#34;)} < / p>
您已经有一个工作版本,另一个版本显示_肯定支持:
列表(&#34; a&#34;,&#34; b&#34;)。foreach(System.out println&#34; Valor =&#34; + _)
上述工作导致评估顺序相当于:
列表(&#34; a&#34;,&#34; b&#34;)。foreach(x =&gt; System.out println&#34; Valor =&#34; + x)