【问题标题】:What does the block argument to Array#first do?Array#first 的 block 参数有什么作用?
【发布时间】:2016-09-13 17:51:19
【问题描述】:

我的记忆力最差,我忘记了Array#find

所以我写了一些代码,使用Array#first 来获取第一个匹配条件的项目:

first_even_num = [1,2,3].first { |x| x % 2 == 0 }

这不起作用,它只是返回数组的第一个元素,无论条件是什么。该块根本没有被调用:

[1,2,3].first { |x| exit }
puts "the program did not exit"

我已经接受 Array#first 并没有像想象的那样做,但我很好奇为什么上述示例没有引发错误。

查看2.3.1 源,唯一记录在案的参数是一个表示返回结果数量的整数。

我不太了解 C,但这就是底层 Array#first 方法作为参数签名的内容:

rb_ary_first(int argc, VALUE *argv, VALUE ary)

我只是想知道为什么提供给Array#first 的块如果什么都不做就不会引发错误。

【问题讨论】:

  • 您可以将块传递给 any 方法。由方法来调用它或检查它的存在。
  • 顺便说一句,我很确定以前有人问过这个问题。谁能找到副本?
  • @Stefan:是的,应该被问过很多次。尝试了几个查询,未能产生匹配。 ://

标签: ruby


【解决方案1】:

您可以将块传递给任何方法,绝对是任何方法。如果它不需要该块,它就不会使用它。这不是错误(因为 block 不是参数之一。它是方法的单独输入)

【讨论】:

  • 为什么 Ruby 不理会这个块?因为她不知道该方法是否会屈服于块,例如,这可能取决于条件表达式的结果。此外,她没有必要检查内置方法Array#first,因为任何方法都可能在运行时被修改。
  • @CarySwoveland:你认为是她吗? :)
  • 我猜如果有Boy Named "Sue" 可能还有另一个名为“Ruby”,但是...
【解决方案2】:

关于 Ruby 和块有一些简单的规则。

  1. 您可以将块传递给任何方法。

  2. 该方法可以选择在从现在到遥远未来的任何时间点运行您的区块零次或多次

  3. 您必须阅读文档或方法实现以了解是否、如何以及何时执行块。没有其他方法可以知道。

您将块传递给不期望的方法的示例与这些规则一致。实际上,它的运行次数为零,并且与 first 调用的结果无关。

【讨论】:

    【解决方案3】:

    您可以通过执行以下操作来获得结果。

    def get_first_even(arr)
    if arr.first % 2 == 0
        first_even_num = arr.first
        puts first_even_num
    else
        arr.delete_at 0
        get_first_even arr
    end
    end
    
    get_first_even [1,3,5,7,9,23,13,14,11,12]   
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-09
      • 1970-01-01
      • 1970-01-01
      • 2019-06-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多