爱国者*_*爱国者 5 c java scala operator-precedence
首先我宣布一个类:
class Op(var x : Int) {
def +++(op: Op) = {
println(this.x + " +++ " + op.x)
this.x += op.x
this
}
def ***(op: Op) = {
println(this.x + " *** " + op.x)
this.x *= op.x
this
}
}
Run Code Online (Sandbox Code Playgroud)
现在我在REPL中执行表达式:
op1 +++ op2 +++ op3 *** op4
Run Code Online (Sandbox Code Playgroud)
它输出

但为什么这个方法不是***先行?是不是优先级***高于+++?Java和C怎么样?它和Scala一样吗?
Kim*_*bel 13
op1 +++ op2 +++ op3 *** op4
Run Code Online (Sandbox Code Playgroud)
相当于
((op1 +++ op2) +++ (op3 *** op4))
Run Code Online (Sandbox Code Playgroud)
因为方法调用是左关联的.因此首先(op1 +++ op2)进行评估,因为它是第二个的第一个操作数+++.然后(op3 *** op4)评估第二个操作数.最后,评估最外层的运算符.
op1 + op2 + op3 * op4在C或Java中也是如此.
有两个规则决定了op1 +++ op2 +++ op3 *** op4表达式评估的顺序:
首先,因为以*开头的运算符优先于以+开头的运算符,所以表达式转换为:
op1 +++ op2 +++ (op3 *** op4)
Run Code Online (Sandbox Code Playgroud)
其次,因为有多个相同优先级的运算符并排出现(op1 +++ op2 +++ ...),所以它们从左到右分组:
(op1 +++ op2) +++ (op3 *** op4)
Run Code Online (Sandbox Code Playgroud)
请考虑以下表达式:
op1 +++ op2 +++ op3 +++ op4 *** op5
Run Code Online (Sandbox Code Playgroud)
遵循相同的两个简单规则,它将被评估为:
((op1 +++ op2) +++ op3) +++ (op4 *** op5)
Run Code Online (Sandbox Code Playgroud)
或者,让我们将相同的两条规则应用于op1 +++ op2 +++ op3 +++ op4 *** op5 *** op6:
以*开头的运算符优先于以+开头的运算符:
op1 +++ op2 +++ op3 +++ (op4 *** op5 *** op6)
Run Code Online (Sandbox Code Playgroud)
然后从左到右分组具有相同优先级的运算符:
((op1 +++ op2) +++ op3) +++ ((op4 *** op5) *** op6)
Run Code Online (Sandbox Code Playgroud)
如果分组+++和***方法没有任何副作用,则分组具有完美的数学意义.考虑:
op1 +++ op2 +++ op1 *** op2
Run Code Online (Sandbox Code Playgroud)
直观地表达应返回的物体保持5.然而,由于不幸的副作用+++和***方法产生的原代码样品(两者修改存储在对象内的值)的表达将导致对象保持12而不是预期5 .
这就是为什么在构造这样的表达式时最好完全依赖不可变对象:
case class Op ( x: Int) {
def +++(that: Op) = {
println(this.x + " +++ " + that.x)
Op(this.x+that.x)
}
def ***(that: Op) = {
println(this.x + " *** " + that.x)
Op(this.x * that.x)
}
}
Run Code Online (Sandbox Code Playgroud)
该Op(1) +++ Op(2) +++ Op(1) *** Op(2)表达式将导致Op(5),符合市场预期.
| 归档时间: |
|
| 查看次数: |
255 次 |
| 最近记录: |