为什么表达式(true == true == true)会产生语法错误?

时间:2018-01-09 00:02:39

标签: ruby syntax-error operators operator-precedence associativity

红宝石

true == true == true
  

语法错误,意外的tEQ

VS。的的JavaScript

true == true == true
// => true

VS。 C

1 == 1 == 1
// => 1

3 个答案:

答案 0 :(得分:49)

对于==方法,没有为===方法定义控制参数评估的运算符顺序的关联方向,与!==~<=>()个方法(所有方法都具有相同的优先级,并且只能形成一个单独的优先级组。)

Documentation

因此,如果上述列表中的多个运算符连续链接的情况下的评估顺序应通过

明确设置
  • 括号(true == true) == true # => true true == (true == true) # => true

    .
  • 或点运算符true .== true == true # => true 可以省略连续的最后一次检查):

    Vector3 up = new Vector3(0, 0, 1); // up side of your circle
    Vector3 tangent = Vector3.Cross(normal, up);
    

答案 1 :(得分:6)

TL; DR语法暗示所有3个值都相等,这不是它在javascript或C中的作用,因此ruby给出了语法错误,将来可以实现此门。

如果我正确地理解了这个问题value_a == value_b == value_c只应该返回true,如果它们都是eqel使用==作为比较操作符,如此方法所示

# version 1
def compare_3_values(a, b, c)
  a == b && a == c && b == c
end
但是,还有另一种可能的预期结果。实现这一点,如上一个答案所示:

#version 2
def compare_3_values(a, b, c)
  (a == b) == c
end

结果是分开的。

JavaScript总是使用版本2,这是非常无用的,因为第3项始终与true或false进行比较(如果第3项是整数,则为0或1),这就是false == false == true返回true的原因。

为了确保如果一个方法是三个值中的一个,它只被调用一次,我们必须创建所有三个变量的副本(而不是引用),然后进行这样的比较:

def compare_3_values(a_original, b_original, c_original)
  #duplicate all three values as a, b, c
  a, b, c = a_original.dup, b_original.dup, c_original.dup

  a == b && b == c && a == c
end
  

好消息是因为ruby提供了语法错误,因此它是唯一可以在不破坏每个人代码的情况下实现此功能的语言。

     

对于任何其他语言来说,它会破坏如此多的代码,即使它是在后来的主要版本中实现的,也需要有一个标志/设置来在未来几年打开或关闭它,因此它永远不值得

Ruby中的一些有趣结果

false .== false == true
=> true

false .== true == false
=> true

true .== false == false
=> true

false .== false == false
=> false

true .== true == false
false

并在javascript中

false == false == true
=> true

false == true == false
=> true

true == false == false
=> true

false == false == false
=> false

true == true == false
=> false
在C中测试的

编辑,与JavaScript类似,因为它将前两个值的结果与第三个值进行比较

答案 2 :(得分:4)

first answer非常出色,但万一并不完全清楚(人们会问为什么),这里有更多的例子。

在C中,==运算符是从左到右的关联,布尔值表示为1(真)和0(假),因此第一个1 == 1求值为1 (true)然后你用第二个表达式评估第一个表达式的结果。你可以尝试:

2 == 2 == 2 // => 0

在C中,评估为:

(2 == 2) == 2
1 == 2 // => 0

在Javascript中,与C类似,==从左到右关联。让我们这次尝试0(虽然C中的相同例子也可以):

0 == 0 == 0
false

再次:

0 == 0 == 0
true == 0 // => false

在Ruby ==中没有关联属性,即。它不能在单个表达式中多次使用,因此无法计算表达式。为什么做出这个决定是该语言作者的问题。此外,Ruby没有将数字1定义为布尔值,因此1 == true的计算结果为false。

second answer表示Ruby中存在一些“怪异”的情况,但它们都按预期进行评估:

(1 == 1) == 1
true == 1 # => false

1 == (1 == 1)
1 == true # => false

1 .== 1 == 1
(1 == 1) == 1
true == 1 # => false

false .== false == true
(false == false) == true
true == true # => true

false .== true == false
(false == true) == false
false == false # => true

true .== false == false
(true == false) == false
false == false # => true

false .== false == false
(false == false) == false
true == false # => false

true .== true == false
(true == true) == false
true == false # => false