【问题标题】:Ruby's one liner "and return"Ruby 的一个班轮“然后返回”
【发布时间】:2014-07-04 19:48:01
【问题描述】:

我最近发现了一个我不完全理解的 Ruby 问题。那么,有人可以向我解释为什么 Ruby 中的以下 2 个语句不一样-

puts "foo" and return if true

VS

if true
  puts "foo" 
  return 
end

【问题讨论】:

    标签: ruby styles return


    【解决方案1】:

    要理解您问题中的单行符,您需要记住 Ruby 运算符及其优先级。或者,更准确地说,Ruby 语法。您需要以与 Ruby 解释器完全相同的方式查看语句。它必须成为你的第二天性。现在让我们看看你的单线

    puts "foo" and return if true
    

    让我们先把不相关的问题分开。关键字 return 仅适用于方法或 lambda,并不是您问题的真正主题。此外,尾随if true 始终有效,因此似乎没有必要。为了一般性地讨论您的问题,让我们定义方法 #bar 和变量 baz

    def bar
      puts "bar"
    end
    
    baz = true
    

    让我们谈谈修改后的单线

    puts "foo" and bar if baz
    

    如果您已经记住了 Ruby 语法,您将能够完全按照 Ruby 看到的方式为该行加上括号:

    ( puts( "foo" ) and ( bar ) ) if ( baz )
    

    尾随if 的行为类似于优先级很低的运算符。仅当 baz 为 true 时,才会执行从开头到 if 的整行,它确实如此。因此,

    puts "foo" and bar
    

    被执行。括号内如下:

    puts( "foo" ) and ( bar )
    

    可以看到puts "foo"先被执行,在屏幕上打印foo并返回nil。由于nil 是错误的,运算符and 只是返回它,而其右侧的bar 永远不会被执行。

    至于

    if baz
      puts "foo"
      bar
    end
    

    相当于:

    ( puts( "foo" ); bar ) if ( baz )
    

    可以看出区别:puts "foo"bar不是由and连接的,而是独立的逻辑行。第一行的返回值被丢弃,不影响第二行的执行。

    最后,让我们看看将and 替换为&& 会发生什么。因为&&操作符的优先级比and高很多,所以oneliner

    puts "foo" && bar
    

    变成

    puts( "foo" && bar )
    

    换句话说,"foo" && bar 的值将首先被计算,然后作为参数传递给#puts 方法。因为字符串"foo" 被认为是真的,所以执行继续到bar,它在屏幕上打印"bar" 并返回nil。你可以自己试试看的值

    "foo" && bar
    

    nil,作为副作用在屏幕上打印"bar"

    puts( "foo" && bar )
    

    就变成了

    puts( nil )
    

    这会导致在屏幕上打印一个空行。

    士气是应该学习语法。 Ruby 设计师迈出了一大步,使代码像书一样一目了然。

    【讨论】:

    • 感谢您的解释。但是声明“用户不应该懒惰地学习它的一小步”。有点居高临下。
    • @Jonathan,如果这听起来对某些人居高临下,我深表歉意。我自己还没有完全达到理想的流利程度。我只是想强调 Matz 为使语言尽可能接近人类句子而付出的巨大努力。这是一个很大的礼物,与发明它所需的努力相比,学习它所需的努力要小得多。我想说,用户得到的奖励是如此之大,以至于学习语法的步骤与它相比会显得很小。我的意思是鼓励,而不是暗示不良品质。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-24
    • 2016-08-23
    相关资源
    最近更新 更多