Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/blackberry/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 2中的命名参数_Ruby_Ruby 2.0 - Fatal编程技术网

Ruby 2中的命名参数

Ruby 2中的命名参数,ruby,ruby-2.0,Ruby,Ruby 2.0,我不完全理解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(var

我不完全理解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

首先,你发布的最后一个例子具有误导性。我完全不同意这种行为与以前的行为相似。最后一个示例将参数hash作为第一个可选参数传入,这是另一回事

如果不希望有默认值,可以使用
nil

如果您想阅读好的书写,请参阅“

根据”,您必须具有默认值:

在Ruby 2.0.0中,关键字参数必须具有默认值,否则必须在末尾由**额外捕获


您可以定义命名参数,如

def test(var1: var1, var2: var2, var3: var3)
  puts "#{var1} #{var2} #{var3}"
end
如果不传递其中一个参数,Ruby将抱怨一个未定义的局部变量或方法

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. 
例如:

  def test(a = 1, options_hash)
    b = options_hash[:b] || 2
    c = options_hash[:c] || 3
    p [a,b,c]
  end

我认为你更新的问题的答案可以用明确的例子来解释。在下面的示例中,您有显式顺序的可选参数:

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'
命名参数方法不同。它仍然允许您提供默认值,但允许调用者确定要提供的参数(如果有):

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'

虽然这两种方法在没有参数的情况下是相似的,但是当用户向方法提供参数时,它们是不同的。通过命名参数,调用方可以指定要提供的参数。具体而言,最后一个示例(仅提供地址)在第一个示例中不太可能实现;只有向方法提供这两个参数,才能获得类似的结果。这使得命名参数的方法更加灵活。

我同意你的观点,使用命名参数需要默认值作为代价是很奇怪的,显然Ruby维护人员同意我们的观点!Ruby 2.1将。

从开始,您不再需要为命名参数设置默认值。如果省略参数的默认值,调用方将需要提供它

def concatenate(val1: 'default', val2:)
  "#{val1} #{val2}"
end

concatenate(val2: 'argument')
#=> "default argument"

concatenate(val1: 'change')
#=> ArgumentError: missing keyword: val2

鉴于:

def test1(var1="default value123")
  var1
end

def test2(var1:"default value123")
  var1
end
当未传递参数时,它们的行为方式相同:

test1
#=> "default value123"

test2
#=> "default value123"
但当一个论点被通过时,他们的行为会大不相同:

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"

这一点在所有其他答案中都有体现,但我想从中提取精华

有四种参数:

             Required     Optional
Positional | def PR(a)  | def PO(a=1) |
Keyword    | def KR(a:) | def KO(a:1) |
定义函数时,位置参数在关键字参数之前指定,必需参数在可选参数之前指定

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]

编辑:从Ruby 2.1.0开始,所需的关键字参数(没有默认值)是新的,正如其他人所提到的。

将此保留在这里,因为它对我帮助很大

例子 假设你有:

def foo(东西,打印)
如果要打印
放东西
结束
结束
#这很有效
福(“你好,真的”)
#嗨
#=>零
因此,请尝试添加参数名称,如下所示:

foo(事物:“hi”,to_print:true)
#foo(事物“hi”,to_print:true)
#ArgumentError:参数数目错误(给定1,应为2)
#from(pry):42:in'foo'
但不幸的是,这是一个错误

解决方案 只需在每个参数的末尾添加一个

test1
#=> "default value123"

test2
#=> "default value123"
def foo2(东西:,打印:)
如果要打印
放东西
结束
结束
foo2(事物“hi”,to_print:true)
#嗨
#=>零

而且它有效

另外,请看一个好的概述。它不同于C#或Java中的默认参数。第一个参数是可选的。最后一个已命名参数。因此,您可以忽略这两个示例的参数,但如果要传入一个参数,则需要对最后一个参数进行命名。第一个示例的可能重复项没有使用命名参数。重复项不是关于Ruby 1的,因为Ruby 2.1不需要将默认值+1赋给。这是一个很容易理解的第一次阅读的描述。猜猜什么很糟糕!如果您定义了一个接受关键字参数的函数,然后有人用普通参数调用它。。。您得到的是
ArgumentError:参数数量错误(1代表0)
,而不是,哦,比如
ArgumentError:关键字参数缺少关键字(参数1,共1个)
。我认为一种常见模式是在参数列表太长或选项太多时使用命名参数。在这些情况下,您可能希望防止人们仅仅将值作为参数传递,并假设他们知道正确的顺序。我使用它们来避免这种反模式:
def(arg1,arg2,flag=true)
I而不是
def(arg1,arg2,flag:true)
因此,调用函数的人必须知道标志的性质。我的意见主要是错误消息的性质应该更明确地说明出错的原因:您没有使用错误的参数数量,只是未能正确命名其中一些参数。@Ziggy对于带有默认值的关键字参数,但是,真的没有办法知道您是否使用了错误的参数数量,或者只是没有正确地命名它们。e、 g.使用
def func(标志:true)
func()
完全有效<但是,code>func(1)包含的参数太多,就像
func(1,标志:false)
一样。我认为错误消息可能会更有帮助,尽管它可能会提示错误指定的参数,或者打印方法签名。我认为这个答案比选择的正确答案要好得多,应该标记为正确答案。为了清楚起见,我只想补充一点,如果您调用第一种方法(使用默认值,但不使用命名参数)如果它是命名参数,则不会出现错误