Ruby 2 中的命名参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15308163/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Named parameters in Ruby 2
提问by Alan Coromano
I don't understand completely how named parameters in Ruby 2.0 work.
我不完全理解 Ruby 2.0 中的命名参数是如何工作的。
def test(var1, var2, var3)
puts "#{var1} #{var2} #{var3}"
end
test(var3:"var3-new", var1: 1111, var2: 2222) #wrong number of arguments (1 for 3) (ArgumentError)
it's treated like a hash. And it's very funny because to use named parameters in Ruby 2.0 I mustset default values for them:
它被视为散列。这很有趣,因为要在 Ruby 2.0 中使用命名参数,我必须为它们设置默认值:
def test(var1: "var1", var2: "var2", var3: "var3")
puts "#{var1} #{var2} #{var3}"
end
test(var3:"var3-new", var1: 1111, var2: 2222) # ok => 1111 2222 var3-new
which very similar to the behaviour which Ruby had before with default parameters' values:
这与 Ruby 之前使用默认参数值的行为非常相似:
def test(var1="var1", var2="var2", var3="var3")
puts "#{var1} #{var2} #{var3}"
end
test(var3:"var3-new", var1: 1111, var2: 2222) # ok but ... {:var3=>"var3-new", :var1=>1111, :var2=>2222} var2 var3
I know why is that happening and almost how it works.
我知道为什么会发生这种情况以及它几乎是如何工作的。
But I'm just curious, mustI use default values for parameters if I use named parameters?
但我只是好奇,如果我使用命名参数,我是否必须使用参数的默认值?
And, can anybody tell me what's the difference between these two then?
而且,有人能告诉我这两者之间有什么区别吗?
def test1(var1="default value123")
#.......
end
def test1(var1:"default value123")
#.......
end
采纳答案by phoet
Firstly, the last example you posted is misleading. I totally disagree that the behavior is similar to the one before. The last example passes the argument hash in as the first optional parameter which is a different thing!
首先,您发布的最后一个示例具有误导性。我完全不同意这种行为与之前的行为相似。最后一个示例将参数哈希作为第一个可选参数传入,这是另一回事!
If you do not want to have a default value, you can just use nil.
如果你不想有一个默认值,你可以使用nil.
If you want to read a good writeup, see "Ruby 2 Keyword Arguments".
如果您想阅读一篇好的文章,请参阅“ Ruby 2 关键字参数”。
回答by AndyV
I think that the answer to your updated question can be explained with explicit examples. In the example below you have optional parameters in an explicit order:
我认为可以用明确的例子来解释你更新的问题的答案。在下面的示例中,您具有显式顺序的可选参数:
def show_name_and_address(name="Someone", address="Somewhere")
puts "#{name}, #{address}"
end
show_name_and_address
#=> 'Someone, Somewhere'
show_name_and_address('Andy')
#=> 'Andy, Somewhere'
The named parameter approach is different. It still allows you to provide defaults but it allows the caller to determine which, if any, of the parameters to provide:
命名参数方法是不同的。它仍然允许您提供默认值,但它允许调用者确定要提供哪些参数(如果有):
def show_name_and_address(name: "Someone", address: "Somewhere")
puts "#{name}, #{address}"
end
show_name_and_address
#=> 'Someone, Somewhere'
show_name_and_address(name: 'Andy')
#=> 'Andy, Somewhere'
show_name_and_address(address: 'USA')
#=> 'Someone, USA'
While it's true that the two approaches are similar when provided with no parameters, they differ when the user provides parameters to the method. With named parameters the caller can specify which parameter is being provided. Specifically, the last example (providing only the address) is not quite achievable in the first example; you can get similar results ONLY by supplying BOTH parameters to the method. This makes the named parameters approach much more flexible.
虽然这两种方法在不提供参数时确实相似,但当用户向方法提供参数时它们会有所不同。使用命名参数,调用者可以指定提供哪个参数。具体来说,最后一个例子(只提供地址)在第一个例子中不太可能实现;您只能通过向方法提供两个参数来获得类似的结果。这使得命名参数方法更加灵活。
回答by Josh Diehl
I agree with you that it's weird to require default values as the price for using named parameters, and evidently the Ruby maintainers agree with us! Ruby 2.1 will drop the default value requirement as of 2.1.0-preview1.
我同意你的看法,要求默认值作为使用命名参数的代价是很奇怪的,显然 Ruby 维护者同意我们的观点!从 2.1.0-preview1 开始,Ruby 2.1 将放弃默认值要求。
回答by trliner
As of Ruby 2.1.0, you no longer have to set default values for named parameters. If you omit the default value for a parameter, the caller will be required to provide it.
从Ruby 2.1.0 开始,您不再需要为命名参数设置默认值。如果省略参数的默认值,则调用者将需要提供它。
def concatenate(val1: 'default', val2:)
"#{val1} #{val2}"
end
concatenate(val2: 'argument')
#=> "default argument"
concatenate(val1: 'change')
#=> ArgumentError: missing keyword: val2
Given:
鉴于:
def test1(var1="default value123")
var1
end
def test2(var1:"default value123")
var1
end
They'll behave the same way when not passed an argument:
当不传递参数时,它们的行为方式相同:
test1
#=> "default value123"
test2
#=> "default value123"
But they'll behave much differently when an argument is passed:
但是当传递参数时,它们的行为会大不相同:
test1("something else")
#=> "something else"
test2("something else")
#=> ArgumentError: wrong number of arguments (1 for 0)
test1(var1: "something else")
#=> {:var1=>"something else"}
test2(var1: "something else")
#=> "something else"
回答by Chris Cox
This is present in all the other answers, but I want to extract this essence.
这存在于所有其他答案中,但我想提取这一本质。
There are four kinds of parameter:
有四种参数:
Required Optional
Positional | def PR(a) | def PO(a=1) |
Keyword | def KR(a:) | def KO(a:1) |
When defining a function, positional arguments are specified before keyword arguments, and required arguments before optional ones.
定义函数时,位置参数在关键字参数之前指定,必需参数在可选参数之前指定。
irb(main):006:0> def argtest(a,b=2,c:,d:4)
irb(main):007:1> p [a,b,c,d]
irb(main):008:1> end
=> :argtest
irb(main):009:0> argtest(1,c: 3)
=> [1, 2, 3, 4]
irb(main):010:0> argtest(1,20,c: 3,d: 40)
=> [1, 20, 3, 40]
edit: the required keyword argument (without a default value) is new as of Ruby 2.1.0, as mentioned by others.
编辑:正如其他人所提到的,所需的关键字参数(没有默认值)是 Ruby 2.1.0 的新内容。
回答by Michael Fürstenberg
According to "Ruby 2.0.0 by Example" you must have defaults:
根据“ Ruby 2.0.0 by Example”,您必须具有默认值:
In Ruby 2.0.0, keyword arguments must have defaults, or else must be captured by **extra at the end.
在 Ruby 2.0.0 中,关键字参数必须有默认值,否则必须在末尾被 **extra 捕获。
回答by aaandre
def test(a = 1, b: 2, c: 3)
p [a,b,c]
end
test #=> [1,2,3]
test 10 #=> [10,2,3]
test c:30 #=> [1,2,30] <- this is where named parameters become handy.
You can define the default value and the name of the parameter and then call the method the way you would call it if you had hash-based "named" parameters but without the need to define defaults in your method.
您可以定义默认值和参数名称,然后以您调用它的方式调用该方法,如果您有基于散列的“命名”参数,但无需在您的方法中定义默认值。
You would need this in your method for each "named parameter" if you were using a hash.
如果您使用散列,您将需要在您的每个“命名参数”的方法中使用它。
b = options_hash[:b] || 2
as in:
如:
def test(a = 1, options_hash)
b = options_hash[:b] || 2
c = options_hash[:c] || 3
p [a,b,c]
end
回答by Clemens Helm
You can define named parameters like
您可以定义命名参数,例如
def test(var1: var1, var2: var2, var3: var3)
puts "#{var1} #{var2} #{var3}"
end
If you don't pass one of the parameters, then Ruby will complain about an undefined local variable or method.
如果您不传递其中一个参数,那么 Ruby 会抱怨undefined local variable or method.

