1

电梯代码:

import net.liftweb.util.Helpers._

object test extends App {

  val xml = <div>
    <span name="a">a</span>
    <span name="b">b</span>
  </div>

  val t1 = if (true) {
    "@a" #> "xxx"
  } else {
    "@a" #> "yyy"
  } &
    "@b" #> "zzz"

  val t2 = (if (true) {
    "@a" #> "xxx"
  } else {
    "@a" #> "yyy"
  }) &
    "@b" #> "zzz"

  println("------------- t1 ------------")
  println(t1(xml))

  println("------------- t2 ------------")
  println(t2(xml))

}

输出:

------------- t1 ------------
<div>
    xxx
    <span name="b">b</span>
  </div>
------------- t2 ------------
<div>
    xxx
    zzz
  </div>

奇怪,对吧?唯一的区别是t2包裹if else()

我的朋友反编译了字节码,发现scala编译了t1类似的:

t1 = true ? "@a" #> "xxx" : "@a" #> "yyy" & "@b" #> "zzz"

好像代码是:

 if (true) 
    "@a" #> "xxx"
  else 
    "@a" #> "yyy" &
    "@b" #> "zzz"

哪里错了?

4

2 回答 2

1

我想这与运算符优先级和解析代码的方式有关。要获得非常准确的答案,必须仔细查看 Scala 的规范。

一般来说,我建议编写一个函数 for@a和另一个 for @b,以便在阅读代码时让事情变得更加清晰。例如:

def ta = 
  if (true) "@a" #> "xxx"
  else "@a" #> "yyy"

def tb = "@b" #> "zzz"

val t1 = ta & tb

与许多其他编程语言不同,Scala 有一种非常轻量级的语法,它鼓励这样的定义。使用它时,您的代码往往更具可读性。看看 Odersky 关于Scala with Style的演讲。他还解释了其他有趣的技巧。

于 2013-06-28T08:17:42.500 回答
1

没有错误。{ } 围绕单个语句不会对代码进行任何更改。记住,块的结果是最后一条语句的结果,所以如果你只有一个,你也可以省略{}。但是,即使您有多个语句, & 也是首先绑定的,请参见示例

if (false) {true; 1} else {false; 3} & {true; 2}

结果是 2(3&2 的结果)。

于 2013-06-28T09:26:17.823 回答