将散列传递给函数(* args)及其含义


72

使用以下成语时:

def func(*args)
  # some code
end

是什么意思*args?谷歌搜索这个特定的问题非常困难,我什么也找不到。

似乎所有参数实际上都出现在其中,args[0]因此我发现自己编写了防御性代码,例如:

my_var = args[0].delete(:var_name) if args[0]

但是我敢肯定,还有一种更好的方法我会错过。

Answers:


104

*图示(或星号)运算符。在方法的上下文中,它指定一个可变长度的参数列表。在您的情况下,所有传递给的参数func都将放入称为的数组中args。您还可以在可变长度参数之前指定特定的参数,如下所示:

def func2(arg1, arg2, *other_args)
  # ...
end

假设我们调用此方法:

func2(1, 2, 3, 4, 5)

如果您检查arg1arg2other_argsfunc2现在,你将得到如下结果:

def func2(arg1, arg2, *other_args)
  p arg1.inspect       # => 1
  p arg2.inspect       # => 2
  p other_args.inspect # => [3, 4, 5]
end

就您而言,您似乎正在将哈希作为参数传递给您func,在这种情况下args[0],正如您所观察到的那样,它将包含哈希。

资源:


根据OP的评论进行更新

如果要传递哈希作为参数,则不应使用splat运算符。Ruby使您可以在方法调用中省略方括号,包括那些指定哈希(带有警告,请继续阅读)的方括号。因此:

my_func arg1, arg2, :html_arg => value, :html_arg2 => value2

相当于

my_func(arg1, arg2, {:html_arg => value, :html_arg2 => value2})

当Ruby=>在您的参数列表中看到运算符时,即使没有显式{...}符号,它也知道将参数作为Hash进行处理(请注意,仅当hash参数为最后一个参数时才适用)。

如果要收集此哈希,则无需执行任何特殊操作(尽管您可能希望将空哈希指定为方法定义中的默认值):

def my_func(arg1, arg2, html_args = {})
  # ...
end

因此if args[0],访问参数时必须使用防御技术吗?
shmichael 2010年

@shmichael您如何调用您的方法?如果您不希望将参数放入这样的数组中,请不要使用splat。
Daniel Vandersluis,2010年

我正在使用Rails约定(例如my_func arg1, arg2, :html_arg => value, :html_arg2 => value2)。理想情况下,我希望接收一个args 哈希,而不是一个args 可能包含哈希数组
shmichael
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.