Ruby 中的 yield 关键字 ( 下 )

yufei       5 年, 8 月 前       1170

Ruby 中的 yeild 关键字 ( 上 ) 中我们学习了 Ruby 中的 ( block ) 的概念和 yield 关键字的基本用法。当然了,上一章节讲的有点太底层了,可能会让还不太熟悉的你一头雾水。

本章节,我们通过一些简单的用例来加深 yield 的用法。

Array#my_map

Enumerable#map 方法允许我们迭代对象列表并操作它们中的每一个元素。 然后返回一个包含所有被操作对象的新列表

$> array = [1, 2, 3]
 => [1, 2, 3]
$> array.map {|n| n + 2}
 => [3, 4, 5]
$> array
 => [1, 2, 3]

上面的代码中,我们首先给 array 变量赋值 [1,2,3] 。然后我们调用 array.map{|n| n+2 } 将数组中的每个元素都 +2 ,然后返回一个新数组 [2,4,6]

最后,我们可以看到,原来的数组 array 并没有改变。

接下来。我们尝试在 Array 类上实现我们自己的 Enumerable#map 版本

class Array
  def my_map
    ary = []
    self.each do |elem|
      ary << yield(elem)
    end
    ary
  end
end
$> array = [1, 2, 3]
 => [1, 2, 3]
$> array.my_map {|n| n + 2}
 => [3, 4, 5]
$> array
 => [1, 2, 3]

从上面的代码中可以看到,我们自定义的 map 方法会行为和官方的 Enumerable#map 是一样的。

超级棒,现在我们来分析下这段代码

  1. 我们创建一个名为 ary 的临时数组 ( Array )。 该变量将包含我们自定义方法的返回值
  2. 我们使用 self.each 迭代接收器 Array
  3. 对于每个元素,我们都执行一次 yield(elem) - 其中 elem 是迭代器当前的元素,然后我们把 yeild(elem) 的返回值存储到 ary 数组中。
  4. 返回 ary 数组

如果我们不传递块 ( block ) 给我们的 Array#my_map 会发生什么情况么 ?

$> array.my_map
LocalJumpError (no block given (yield))

可能正如你所预见的那样,抛出了一个异常。

幸运的是,我们已经在前面的章节中讲解了如何修复这个问题,我们所要做的就是利用 Kernel#block_given? 来增强我们的 Array#my_map 方法

class Array
  def my_map
    return self.dup unless block_given?
    ary = []
    self.each do |elem|
      ary << yield(elem)
    end
    ary
  end
end
$> array.my_map
 => [1, 2, 3]

这样,当不传递任何块给 Array#my_map 也不会报错,而且会直接返回原数组的一个拷贝

目前尚无回复
简单教程 = 简单教程,简单编程
简单教程 是一个关于技术和学习的地方
现在注册
已注册用户请 登入
关于   |   FAQ   |   我们的愿景   |   广告投放   |  博客

  简单教程,简单编程 - IT 入门首选站

Copyright © 2013-2022 简单教程 twle.cn All Rights Reserved.