某个 method 需要传很多不确定的参数,以下两种姿势有什么区别么?大家一般会怎么写?
def foo **options puts options.inspect end
def bar options puts options.inspect end
foo msg: 'hello' bar msg: 'world'
歪楼了。楼主就想知道 *options 和 options 的区别。 这里一个的意思看这里: https://stackoverflow.com/questions/918449/what-does-the-unary-operator-do-in-this-ruby-code/918475#918475
*options 在参数里就是用 options 代替一个参数 Array,在前面再有一个就是展开这个 Array
这个其实关乎方法参数位置的问题。
def a_method a, b="yo", *msgs, c, key_param: "value", **options, &block
puts "a=#{a}"
puts "b=#{b}"
puts "msgs=#{msgs}"
puts "c=#{c}"
puts "key_param: #{key_param}"
puts "options: #{options}"
puts "block: #{block.call}"
end
a_method "called", "with", "lots", "of", "params", and: "a custom key param" do
"and a block"
end
产出
a=called
b=with
msgs=["lots", "of"]
c=params
key_param: value
options: {:and=>"a custom key param"}
block: and a block
# ruby不允许这样的语法( options默认值如果不是hash话无法传值,并且编译器分析不出来
def a b: 1, options = {}
end
# 所以这种情况只能用
def a b: 1, **options
end
#8 楼 @ruohanc #10 楼 @jjym #12 楼 @Rei 谢谢各位提供的信息,另外似乎不加**传递的是引用,加上就变成传值了,是这样吧?
def foo **options
options[:foo] = true
end
options = {msg: 'hello'}
foo options
puts options.inspect
=> {:msg=>"hello"}
def bar options
options[:bar] = true
end
options = {msg: 'hello'}
bar options
puts options.inspect
=> {:msg=>"hello", :bar=>true}
object_id 不一样
语法的区别我在 #10 说了
2.1.2 :001 > def foo **options
2.1.2 :002?> options[:foo] = true
2.1.2 :003?> p options.object_id
2.1.2 :004?> end
=> :foo
2.1.2 :005 > options = {msg: 'hello'}
=> {:msg=>"hello"}
2.1.2 :006 > p options.object_id
14588640
=> 14588640
2.1.2 :007 > foo options
14573680
=> 14573680
2.1.2 :008 > p options
{:msg=>"hello"}
=> {:msg=>"hello"}