将一长串变量作为参数传递给方法的最佳方法是什么?
def foo(a,b,c,d,e,f) # Could this be shorter? No?
puts f + " loves " + e
# dad loves you
end
egg = "Chicken"
girl = "Money"
car = "luxury"
rich = "poor"
me = "you"
mom = "dad"
foo(egg, girl, car, rich, me, mom)
有foo(a..f)
的内容吗?是的,如果可能的话,它不会工作,但正在寻找简短而整洁的东西。
答案 0 :(得分:1)
egg = "Chicken"
girl = "Money"
car = "luxury"
rich = "poor"
me = "you"
mom = "dad"
def foo(*args)
puts "#{args[-1]} loves #{args[-2]}"
end
foo(*[egg, girl, car, rich, me, mom]) # dad loves you
def foo(**params)
puts "#{params[:mom]} loves #{params[:me]}"
end
foo(me: me, mom: mom) # dad loves you
双splat默认值:
def foo(me: 'you', mom:, **params)
puts "#{mom} loves #{me}"
end
foo(mom: mom) # dad loves you
答案 1 :(得分:0)
方法可以通过在参数前加上*(splat)或**(双splat)运算符来获取任意数量的参数。当方法定义中未知确切的参数数量时,这非常有用。
首先让我们看一下*(splat)运算符。通过前缀为*的参数传递的所有参数都自动存储在数组中。
def list_masters *names
print names
end
# Call the method and pass it three arguments
list_masters "Shunryu Suzuki", "Thich Nhat Hanh", "Kodo Sawaki"
Output:
["Shunryu Suzuki", "Thich Nhat Hanh", "Kodo Sawaki"]
注意输出是一个数组。
Ruby中的splat运算符还有其他用途,例如在将数组传递给方法时展开数组,将值强制转换为数组并解构数组,但这些不在本文的讨论范围之内。
现在让我们看看**(双splat)运算符。它是在Ruby 2.0中引入的,并且以与单个splat运算符类似的方式工作,除了它将参数存储在散列而不是数组中。我们来试试吧:
def meditate **details
print details
end
# Call the method and pass it three arguments
meditate mat: "zabuton", cushion: "zafu", practice: "shikantaza", time: 40
Output:
{:mat=>"zabuton", :cushion=>"zafu", :practice=>"shikantaza", :time=>40}
请注意,输出是一个哈希值。
前缀为double splat的参数只接受关键字参数,例如分钟:40或冥想:“zazen”。
如果方法同时包含单个splat参数和双splat参数,则前缀为*的参数将采用非关键字参数,并且将使用前缀为**的参数获取哈希参数。例如:
def meditate *practices, **details
puts "Practices: #{practices}"
puts "Details: #{details}"
end
meditate"zazen", "kinhin", duration: 40, time: "morning"
Output:
Practices: ["zazen", "kinhin"]
Details: {:duration=>40, :time=>"morning"}
请注意,通过* practices参数传递的参数已插入到数组中,通过** details参数传递的参数存储在哈希中。
当方法包含*和**参数时,应首先提供所有位置参数,然后提供关键字参数。如果我们尝试调用上面的方法并首先提供关键字参数,则会抛出语法错误:
meditate time: "morning", duration: 40, "zazen", "kinhin"
Output:
SyntaxError: (irb):59: syntax error, unexpected ',', expecting =>
meditate time: "morning", duration: 40, "zazen", "kinhin"
^