我不完全理解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)
它被当作一个哈希值来处理,这非常有趣,因为在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
这与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
我知道为什么会这样,也知道它是如何运作的。
但我只是好奇,如果我使用命名参数,必须我使用参数的默认值吗?
有谁能告诉我这两者之间有什么区别吗?
def test1(var1="default value123")
#.......
end
def test1(var1:"default value123")
#.......
end
9条答案
按热度按时间tktrz96b1#
我认为你的问题可以用明确的例子来解释。在下面的例子中,你有一个明确顺序的可选参数:
命名参数方法是不同的,它仍然允许您提供默认值,但它允许调用者确定要提供哪些参数(如果有的话):
虽然这两种方法在不提供参数的情况下是相似的,但当用户为方法提供参数时,它们就不同了。使用命名参数,调用者可以指定要提供哪个参数。特别是,最后一个示例(只提供地址)在第一个示例中不太容易实现;你可以只通过提供两个参数给方法来得到相似的结果。2这使得命名参数方法更加灵活。
35g0bw712#
你发布的最后一个例子是误导性的。我不同意行为与前一个相似。最后一个例子将参数散列作为第一个可选参数传递进来,这是不同的事情!
如果不想使用默认值,可以使用
nil
。如果你想读一篇好的评论,请参阅“Ruby 2 Keyword Arguments“。
t0ybt7op3#
从Ruby 2.1.0开始,您不再需要为命名参数设置默认值,如果您省略了参数的默认值,调用者将需要提供它。
给定:
当没有参数传递时,它们的行为是一样的:
但是当传递参数时,它们的行为会大不相同:
5hcedyr04#
我同意你的观点,使用命名参数需要默认值是很奇怪的,显然Ruby维护者也同意我们的观点!
4bbkushb5#
这一点在所有其他答案中都存在,但我想提取出这一本质。
有四种参数:
| | 必需|可选|
| - ------|- ------|- ------|
| 位置|
def PR(a)
|def PO(a=1)
|| 关键词|
def KR(a:)
|def KO(a:1)
|定义函数时,位置参数在关键字参数之前指定,必选参数在可选参数之前指定。
6rqinv9w6#
把它留在这里是因为它帮了我很多。
示例
假设你有这样的:
所以你试着添加参数名,像这样:
但不幸的是它出错了。
溶液
只需在每个参数的末尾添加一个
:
:而且很管用!
ykejflvf7#
根据“Ruby 2.0.0 by Example“,您必须具有默认值:
在Ruby 2.0.0中,关键字参数必须有默认值,否则必须在末尾用**extra捕获。
whlutmcx8#
您可以定义参数的默认值和名称,然后调用该方法,方法的调用方式与使用基于哈希的“命名”参数时相同,但无需在方法中定义默认值。
如果您使用散列,则在方法中的每个“命名参数”都需要此值。
如:
jhdbpxl99#
可以定义命名参数,如
如果您没有传递其中一个参数,Ruby将报告
undefined local variable or method
。