在Ruby中,"&:"运算符有什么功能?

71

3
这是一个重复的问题,已经有不少于17个其他问题在StackOverflow上被问过并得到了答案:Understanding [ClassOne, ClassTwo].each(&:my_method)What does map(&:name) mean in Ruby?What exactly is &:capitalize in Ruby?Ruby/Ruby on Rails ampersand colon shortcutRuby : &:symbol syntax,... - Jörg W Mittag
3
以下这些语句在编程中是什么意思:&:property 表示什么?在以下 ruby 语法中,符号 & 代表什么?为什么要在 ruby 中对属性使用一元运算符,例如 &:firstArray#map 方法如何带参数实现此功能?ruby 中的 &: 是什么意思,它是一个混合着符号的块吗? - Jörg W Mittag
2个回答

122

在Ruby中没有&:运算符。你看到的是将&运算符应用于:symbol的结果。

在方法参数列表中,&运算符获取其操作数,如果它还不是一个Proc对象(通过调用to_proc方法来进行转换),并像使用一个块一样将其传递给方法。

my_proc = Proc.new { puts "foo" }

my_method_call(&my_proc) # is identical to:
my_method_call { puts "foo" }

所以现在的问题变成了“Symbol#to_proc是什么?”,这在Rails文档中很容易看到:

将符号转换为简单的proc,这对于枚举特别有用。例如:

# The same as people.collect { |p| p.name }
people.collect(&:name)

# The same as people.select { |p| p.manager? }.collect { |p| p.salary }
people.select(&:manager?).collect(&:salary)

4
你在暗示这一点,但更好的做法是明确告知:这是Rails进行的修改,并不是Ruby本身内置的功能。 - kikito
8
这是Ruby中Symbol类的文档页面,介绍了其中一个方法to_proc的用法。该方法将符号转化为一个Proc对象,可以方便地将其作为块传递给方法使用。 - tokland
2
你说得对 - 我刚刚在纯 irb (1.8.7) 中尝试了一下,这确实是 Ruby 自身的功能。这个功能并不是 Rails 提供的。感谢指出我的错误! - kikito
7
@kikito说实际上这个功能最初是在Rails中实现的,但由于大家喜欢它,所以它被纳入了核心功能。 - tokland
1
请不要回答重复的问题,只需投票关闭即可。这个问题已经被问过并回答了17次(!!!),将知识进一步分散真的没有任何好处。 - Jörg W Mittag
有没有一种方法可以将参数传递给被调用的方法?例如 salary - Deekor

41

在符号前面添加&,你就创建了一个 lambda 函数,该函数将在传递给它的对象上调用该符号名称的方法。考虑到这一点:

ar.map(&:reverse)

大致等同于:

ar.map { |element| element.reverse }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接