sai*_*ala 16 ruby named-parameters keyword-argument
Ruby 2.0.0支持关键字参数(KA),我想知道在纯Ruby的上下文中这个特性的好处/用例是什么,特别是考虑到由于关键字匹配导致的性能损失,需要每个时间调用带有关键字参数的方法.
require 'benchmark'
def foo(a:1,b:2,c:3)
[a,b,c]
end
def bar(a,b,c)
[a,b,c]
end
number = 1000000
Benchmark.bm(4) do |bm|
bm.report("foo") { number.times { foo(a:7,b:8,c:9) } }
bm.report("bar") { number.times { bar(7,8,9) } }
end
# user system total real
# foo 2.797000 0.032000 2.829000 ( 2.906362)
# bar 0.234000 0.000000 0.234000 ( 0.250010)
Run Code Online (Sandbox Code Playgroud)
Dav*_*vey 17
关键字参数有一些没有人触及的明显优势.
首先,你没有加入参数的顺序.因此,如果您偶尔会有一个零参数,它看起来会更清晰:
def yo(sup, whats="good", dude="!")
# do your thing
end
yo("hey", nil, "?")
Run Code Online (Sandbox Code Playgroud)
如果您使用关键字参数:
def yo(sup:, whats:"good", dude:"!")
# do your thing
end
yo(sup: "hey", dude: "?")
Run Code Online (Sandbox Code Playgroud)
甚至
yo(dude: "?", sup: "hey")
Run Code Online (Sandbox Code Playgroud)
它消除了必须记住参数顺序的需要.但是,缺点是您必须记住参数的名称,但这应该或多或少直观.
此外,当你有一个方法可能需要在将来采取更多的参数.
def create_person(name:, age:, height:)
# make yourself some friends
end
Run Code Online (Sandbox Code Playgroud)
如果你的系统突然想知道一个人最喜欢的糖果棒,或者他们超重(因为消耗了太多他们喜欢的糖果棒)怎么办?你会怎么做?简单:
def create_person(name:, age:, height:, favorite_candy:, overweight: true)
# make yourself some fat friends
end
Run Code Online (Sandbox Code Playgroud)
在关键字参数之前总是存在哈希值,但这导致了更多的样板代码来提取和赋值变量.Boilerplate代码==更多输入==更多潜在的错别字==少写一些令人敬畏的ruby代码.
def old_way(name, opts={})
age = opts[:age]
height = opts[:height]
# all the benefits as before, more arthritis and headaches
end
Run Code Online (Sandbox Code Playgroud)
如果您只是设置一个接受一个参数的方法,并且很可能永远不需要更改:
def say_full_name(first_name, last_name)
puts "#{first_name} #{last_name}"
end
Run Code Online (Sandbox Code Playgroud)
然后应避免使用关键字参数,因为性能影响很小.
从 ruby-2.2.0 开始,使用关键字参数的低效率问题似乎不再是问题。
功能 #10440修复了速度问题并在ruby-2.2.0中发布:
2014 年 11 月 3 日星期一 03:02:38 笹田浩一
- 重写方法/块参数拟合逻辑以优化关键字参数/参数和 splat 参数。功能#10440(此票证中描述了详细信息)
您可以亲自看到这一点(使用与原始问题中给出的相同的代码):
(08:04:%) rvm use ruby-2.0.0-p247
Using /Users/adam/.rvm/gems/ruby-2.0.0-p247
(08:04:%) ruby keyword_benchmarks.rb
user system total real
foo 1.390000 0.060000 1.450000 ( 1.451284)
bar 0.130000 0.000000 0.130000 ( 0.122344)
(08:04:%) rvm use ruby-2.2.0
Using /Users/adam/.rvm/gems/ruby-2.2.0
(08:04:%) ruby keyword_benchmarks.rb
user system total real
foo 0.140000 0.000000 0.140000 ( 0.136194)
bar 0.110000 0.000000 0.110000 ( 0.116246)
Run Code Online (Sandbox Code Playgroud)
使用关键字参数的性能损失仍然可以忽略不计,但我认为这是一个可以接受的权衡,以换取增加可读性和位置灵活性的好处。
例如
\n\n一个功能
\n\ndef welcome_message(message, options={})\n default_options = {name: \'hoge\'}\n options = default_options.merge(options)\n\n "#{message}\xe3\x80\x81#{options[:name]}"\nend\nRun Code Online (Sandbox Code Playgroud)\n\n可以写成
\n\ndef welcome_message(message, name: \'hoge\')\n "#{message}\xe3\x80\x81#{name}"\nend\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
12532 次 |
| 最近记录: |