博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Ruby 的 yield 浅析
阅读量:4229 次
发布时间:2019-05-26

本文共 2615 字,大约阅读时间需要 8 分钟。

今天在书上看到这么一个例子,虽然我多多少少对 Ruby 的 block 有一些了解,但是第一次见到下面这种时,还是有点懵的:

# Rubydef block_args_test  yield()  yield(1)  yield(1, 2, 3)endputs "通过 |a| 接收块变量"block_args_test do |a|  p [a]endputsputs "通过 |a, b, c| 接收块变量"block_args_test do |a, b, c|  p [a, b, c]endputsputs "通过 |*a| 接收块变量"block_args_test do |*a|  p [a]endputs------------------------------------------------------------通过 |a| 接收块变量[nil][1][1]通过 |a, b, c| 接收块变量[nil, nil, nil][1, nil, nil][1, 2, 3]通过 |*a| 接收块变量[[]][[1]][[1, 2, 3]]

所以,为了啃下这块硬骨头,先从一个简单的例子讲起吧!

不带参的块

# Ruby# 定义块def myloop  while true    yield     # 执行块  endendnum = 1myloop do  puts "num is #{num}"  break  if num > 10  num *= 2end------------------------------------------------------------num is 1num is 2num is 4num is 8num is 16

首先是定义块,在定义好块以后,使用块的 do ~ end 语句时,其实质是把块里边的代码:

puts "num is #{num}"  break  if num > 10  num *= 2

放到了 yield 的地方去执行,所以这儿是比较好理解的。

携带参的块

我们把上面的简单例子稍微改造一下,改成可以传参给 block,下面还是可以得到同上面一样的输出。

# Ruby# 定义块def myloop  while true    yield(2)     # 执行块  endendnum = 1myloop do |i|  puts "num is #{num}"  break  if num > 10  num *= iend------------------------------------------------------------num is 1num is 2num is 4num is 8num is 16

虽然比不传参的稍微复杂一点,但是我相信大家还是能看懂的。

传参数目不一致

现在,我们再复杂化一点,块定义的时候设定两个参数,但是 block  执行的时候只给块传一个参数。

# Ruby# 定义块def myloop  while true    yield(2, 3)     # 执行块  endendnum = 1myloop do |i|  puts "num is #{num}"  break  if num > 10  num *= iend------------------------------------------------------------num is 1num is 2num is 4num is 8num is 16

还是一样的结果,似乎多的参数对执行结果并没有什么影响。到现在,我们基本上能把最开始的例子解释一下了。

结果解释

# Rubydef block_args_test  yield()  yield(1)  yield(1, 2, 3)endputs "通过 |a| 接收块变量"block_args_test do |a|  p [a]endputsputs "通过 |a, b, c| 接收块变量"block_args_test do |a, b, c|  p [a, b, c]endputsputs "通过 |*a| 接收块变量"block_args_test do |*a|  p [a]endputs------------------------------------------------------------通过 |a| 接收块变量[nil]  # yield() 没传递参数,所以 a 没接收到参数,a 为 nil[1]    # yield(1) 传递一个参数,所以 a 接收到传递的参数,a 为 1[1]    # yield(1, 2, 3) 传递三个参数,但是只有一个块变量接收,所以接收到第一个参数,a 为 1通过 |a, b, c| 接收块变量[nil, nil, nil]   # yield() 没传递参数,所以三个块变量 a, b, c 均为 nil [1, nil, nil]     # yield() 传递一个参数,所以 a 接收到传递的参数,a 为 1,剩下 2 个块变量 b, c 均为 nil[1, 2, 3]         # yield() 传递三个个参数,a, b, c 三个块变量分别接收一个通过 |*a| 接收块变量# *a 是匹配任意个的意思,所以无论 yield 传递过来多少参数,块变量都会将多个参数变成一个数组# 我们可以来个下面的简单例子印证一下# [20] pry(main)> def test(*args)# [20] pry(main)*   p [args]  # [20] pry(main)* end  # => :test# [21] pry(main)> test(1, 2, 3)# [[1, 2, 3]]# => [[1, 2, 3]][[]]              # yield() 没传递参数,所以 a 为 [][[1]]             # yield() 传递一个参数,所以 a 为 [1][[1, 2, 3]]       # yield() 传递三个个参数,匹配三个参数以后,所以 a 为 [1, 2, 3]

 

 

 

转载地址:http://djjqi.baihongyu.com/

你可能感兴趣的文章
sizeof与strlen
查看>>
一个递归+二分法的洗牌程序
查看>>
YUV格式注释
查看>>
一维、二维数组传参
查看>>
判断当前时间的下一秒是多少
查看>>
从文本文件中读取数据排序并输出到文本
查看>>
求一个整数数组中第二大的数
查看>>
删除一个链表中的节点
查看>>
计算机网络面试整理【转】
查看>>
cookie和session区别详解
查看>>
程序员失业第一步?斯坦福研究员用AI从编译器反馈中学习改Bug
查看>>
原创 | 电视广告流量预测中的“常识”陷阱,你掉进去了吗?
查看>>
DeepMind发布最新《神经网络中持续学习》综述论文!
查看>>
本科三篇顶会一作、超算竞赛冠军,2020清华本科特奖结果出炉
查看>>
多语言互通:谷歌发布实体检索模型,涵盖超过100种语言和2000万个实体
查看>>
你的房东可能正用AI筛查你的犯罪记录,决定要不要租房给你
查看>>
AI把爱豆变胖视频火遍B站,我们找到了背后的技术团队:你是怎么把刘亦菲变胖的?...
查看>>
白硕:区块链技术与数据隐私(附视频)
查看>>
数据蒋堂 | 报表工具的SQL植入风险
查看>>
AAC ADTS LATM 格式分析
查看>>