14

我对 Ruby 中的 and/&&/= 关键字有疑问。

ruby 文档说,上述关键字的优先级是:(1)&&、(2)=、(3)and。

我有我写的这段代码:

def f(n) 
 n
end

if a = f(2) and  b = f(4) then  
    puts "1) #{a} #{b}" 
 end

if a = f(2) &&  b = f(4) then   
    puts "2) #{a} #{b}"     
end

输出是:

1) 2 4 [预期]

2) 4 4 [为什么?]

出于某种原因,使用 && 会导致 a 和 b 都评估为 4?

4

5 回答 5

24

我不太明白你问的问题。我的意思是,你自己已经给出了答案,甚至在问这个问题之前&&:绑定比绑定更紧密,=and绑定比不那么紧密=

因此,在第一种情况下,表达式的计算方式如下:

( a=f(2) )  and  ( b=f(4) )
( a=  2  )  and  ( b=f(4) )
      2     and  ( b=f(4) ) # a=2
      2     and  ( b=  4  ) # a=2
      2     and        4    # a=2; b=4
                       4    # a=2; b=4

第二种情况,评价如下:

a   =   (  f(2) && ( b=f(4) )  )
a   =   (    2  && ( b=f(4) )  )
a   =   (    2  && ( b=  4  )  )
a   =   (    2  &&       4     ) # b=4
a   =                    4       # b=4
                         4       # b=4; a=4
于 2009-12-03T16:15:25.430 回答
21

原因很简单:优先。正如你所说,顺序是:

  1. &&
  2. =

由于&&优先于=,因此该语句的评估方式如下:

if a = (f(2) && (b = f(4))) then 

结果是:

if a = (2 && 4) then

xy是整数时,x && y返回y。因此2 && 4导致a = 4.

为了比较起见,第一个评估如下:

if (a = f(2)) and  (b = f(4)) then 
于 2009-12-03T15:51:03.537 回答
3

编程 Ruby 1.9开始:

两种形式的唯一区别是优先级(and绑定低于&&)。

于 2009-12-03T15:18:06.553 回答
0

我不知道在这种情况下可以提供帮助的具体规则,但让我们使用操作的优先级。使用优先级规则,我们可以将第二个表达式的计算分为几个步骤

1 f(2) &&  b => expr1
2 expr1 = f(4) => expr2
3 a = expr2

很明显,在第 2 步中我们得到了一个不正确的情况 - = 的左侧是右值 - 临时对象,它不能被任何值分配。我假设句法分析器在遇到这种情况时会破坏表达式优先级评估的规则。有关表达式计算的更多详细信息,请参见此处

于 2009-12-03T17:50:06.213 回答
-7

如果你像这样修改你的代码,你会得到你所期望的

def f(n) 
  n
end

if (a = f(2) and  b = f(4)) then  
  puts "1) #{a} #{b}" 
end

if (a = f(2)  and  b = f(4)) then   
  puts "2) #{a} #{b}"         
end

1) 2 4

2) 2 4

于 2009-12-03T15:24:28.587 回答