gpt4 book ai didi

Ruby:Proc#call 与 yield

转载 作者:数据小太阳 更新时间:2023-10-29 06:19:23 26 4
gpt4 key购买 nike

thrice 方法的以下两种 Ruby 实现之间的行为差​​异是什么?

module WithYield
def self.thrice
3.times { yield } # yield to the implicit block argument
end
end

module WithProcCall
def self.thrice(&block) # & converts implicit block to an explicit, named Proc
3.times { block.call } # invoke Proc#call
end
end

WithYield::thrice { puts "Hello world" }
WithProcCall::thrice { puts "Hello world" }

我所说的“行为差异”包括错误处理、性能、工具支持等。

最佳答案

我认为第一个实际上是另一个的语法糖。换句话说,没有行为差异。

虽然第二种形式允许将 block “保存”在变量中。然后可以在其他某个时间点调用该 block - 回调。


好的。这次我去做了一个快速基准测试:

require 'benchmark'

class A
def test
10.times do
yield
end
end
end

class B
def test(&block)
10.times do
block.call
end
end
end

Benchmark.bm do |b|
b.report do
a = A.new
10000.times do
a.test{ 1 + 1 }
end
end

b.report do
a = B.new
10000.times do
a.test{ 1 + 1 }
end
end

b.report do
a = A.new
100000.times do
a.test{ 1 + 1 }
end
end

b.report do
a = B.new
100000.times do
a.test{ 1 + 1 }
end
end

end

结果很有趣:

      user     system      total        real
0.090000 0.040000 0.130000 ( 0.141529)
0.180000 0.060000 0.240000 ( 0.234289)
0.950000 0.370000 1.320000 ( 1.359902)
1.810000 0.570000 2.380000 ( 2.430991)

这表明使用 block.call 几乎比使用 yield 慢 2 倍。

关于Ruby:Proc#call 与 yield,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1410160/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com