Ruby运算符同时作为方法时如何遵循常规优先级?
Ruby运算符:语法糖与非语法糖的执行差异
咱们来聊聊Ruby里运算符调用的一个容易踩坑的细节——同样的运算逻辑,用语法糖和直接调用方法的形式,结果可能完全不同!
语法糖形式:遵循数学优先级
当你用运算符的语法糖(比如+、*这种直观的符号)时,Ruby会严格遵循数学中的优先级顺序来执行运算。举个最常见的例子:
# 语法糖形式 5 + 5 * 2 # => 15
这里乘法*的优先级高于加法+,所以会先计算5*2得到10,再加上5最终得到15,和我们学的数学运算逻辑完全一致。
非语法糖形式:按书写顺序执行
但如果你把运算符当成普通方法来调用(也就是非语法糖形式,用.调用方法名),情况就不一样了——Ruby会完全按照代码书写的线性顺序执行,完全不考虑数学优先级。还是用刚才的例子:
# 非语法糖形式 5.+(5).*(2) # => 20
这里会先执行5.+(5)得到10,接着用这个结果调用*(2),最终得到20,和语法糖形式的结果天差地别。
自定义方法也适用这两种规则
哪怕是你自己定义的类里重写的运算符方法,也同时支持这两种调用形式,并且遵循对应的执行规则。比如我们定义一个WackyInt类:
class WackyInt attr_reader :value def initialize(value) @value = value end def +(other) WackyInt.new(value + other.value) end def *(other) WackyInt.new(value * other.value) end end # 语法糖形式调用,遵循数学优先级 a = WackyInt.new(5) b = WackyInt.new(5) c = WackyInt.new(2) result1 = a + b * c puts result1.value # => 15 # 非语法糖形式调用,按顺序执行 result2 = a.+(b).*(c) puts result2.value # => 20
可以看到,自定义的运算符方法在两种形式下的执行逻辑和内置运算符完全一致。
内容的提问来源于stack exchange,提问作者Eli Sadoff
相关产品推荐
相关产品推荐

