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 には、他の多くのプログラミング言語とは異なり、そのような定義を促進する非常に軽量な構文があります。コードを使用すると、コードがはるかに読みやすくなる傾向があります。Scala with Styleに関する Odersky の講演をご覧ください。彼は他の興味深いトリックも説明します。

于 2013-06-28T08:17:42.500 に答える
1

何も問題はありません。{ } を 1 つのステートメントの周りに配置しても、コードは変更されません。ブロックの結果は最後のステートメントの結果であることを忘れないでください。したがって、1 つしかない場合は { } を省略することもできます。ただし、複数のステートメントがある場合でも、 & が最初にバインドされます。例として参照してください

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

結果は 2 です (3&2 の結果)。

于 2013-06-28T09:26:17.823 に答える