在 Ruby 中,我知道如果这样做:
some_objects.each(&:foo)
这和
some_objects.each { |obj| obj.foo }
也就是说,&:foo
创建了块 { |obj| obj.foo }
,并将其转换为 Proc,并将其传递给 each 方法。为什么会这样工作?这只是 Ruby 的特殊情况,还是有其他原因使其能够正常工作?
在 Ruby 中,我知道如果这样做:
some_objects.each(&:foo)
这和
some_objects.each { |obj| obj.foo }
也就是说,&:foo
创建了块 { |obj| obj.foo }
,并将其转换为 Proc,并将其传递给 each 方法。为什么会这样工作?这只是 Ruby 的特殊情况,还是有其他原因使其能够正常工作?
你的问题可以说是错误的。这里发生的不是“和冒号”,而是“和对象”。在这种情况下,冒号是用于符号的。所以有&
和 :foo
。
&
调用了对象上的 to_proc
方法,并将其作为块传递给方法。在 Ruby 中,to_proc
是在 Symbol
上实现的,因此这两个调用是等效的:
something {|i| i.foo }
something(&:foo)
总结一下:在Ruby中,&
会调用对象的to_proc
方法并将其作为块传递给方法,在Symbol
上实现了to_proc
方法。
p RUBY_VERSION
# => "1.8.7"
p ["a", "b", "c"].map(&:upcase)
# => ["A", "B", "C"]
- August Lilleaas使用“&”符号和“#”符号的组合并没有什么特别之处。这里有一个(滥用)正则表达式的示例:
class Regexp
def to_proc
->(str) { self =~ str ; $1 }
end
end
%w(station nation information).map &/(.*)ion/
=> ["stat", "nat", "informat"]
或整数。
class Integer
def to_proc
->(arr) { arr[self] }
end
end
arr = [[*3..7],[*14..27],[*?a..?z]]
arr.map &4
=> [7, 18, "e"]
当你拥有arr.map &4
时,谁还需要arr.map(&:fifth)
呢?
[*3..7]
的语法。我没想到你可以这样展开! - Ben Coppock