字符串插值和占位符变量

时间:2014-07-03 12:43:06

标签: scala string-interpolation

为什么在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;变量不受支持。

这是一个错误还是设计?

2 个答案:

答案 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)