zen*_*ngr 28 ruby language-agnostic lambda
我试图理解为什么我们真的需要rubda(或任何其他语言)lambda或proc?
#method
def add a,b
c = a+b
end
#using proc
def add_proc a,b
f = Proc.new {|x,y| x + y }
f.call a,b
end
#using lambda function
def add_lambda a,b
f = lambda {|x,y| x + y}
f.call a,b
end
puts add 1,1
puts add_proc 1,2
puts add_lambda 1,3
Run Code Online (Sandbox Code Playgroud)
我可以使用以下方法进行简单的添加:1.正常函数def,2.使用proc和3.使用lambda.
但是为什么以及在现实世界中使用lambda?任何无法使用函数和lambda应该使用的示例.
Ant*_*sky 20
确实,你不需要匿名函数(或lambdas,或任何你想称之为的东西).但也有很多东西你没有需要.您不需要类 - 只需将所有实例变量传递给普通函数.然后
class Foo
attr_accessor :bar, :baz
def frob(x)
bar = baz*x
end
end
Run Code Online (Sandbox Code Playgroud)
会成为
def new_Foo(bar,baz)
[bar,baz]
end
def bar(foo)
foo[0]
end
# Other attribute accessors stripped for brevity's sake
def frob(foo,x)
foo[0] = foo[1]*x
end
Run Code Online (Sandbox Code Playgroud)
同样,除了with 和之外,你不需要任何循环.我可以继续下去.1 但是你想用Ruby编写类.您希望能够使用循环,甚至可以使用循环,并且您希望能够使用循环而不是.loop...end
if
break
while
array.each { |x| ... }
unless
if not
就像这些功能一样,匿名功能可以帮助您优雅,简洁,明智地表达事物.能够写作some_function(lambda { |x,y| x + f(y) })
比写作要好得多
def temp(x,y)
x + f(y)
end
some_function temp
Run Code Online (Sandbox Code Playgroud)
必须中断代码流以写出一个def
fed函数,然后必须给它一个无用的名称,当它在线编写操作时很明显.确实没有地方你必须使用lambda,但有很多地方我宁愿使用lambda.
红宝石解决了很多使用的λ-例块:所有的功能,如each
,map
和open
可以采取一个块作为参数基本上都采取了特例,匿名函数. array.map { |x| f(x) + g(x) }
与array.map(&lambda { |x| f(x) + g(x) })
(&
就像裸块一样)使lambda"特殊"成为一样.同样,你可以写出一个单独的def
每一次,但为什么你会馈功能要来?
支持这种编程风格的Ruby之外的语言没有块,但通常支持更轻量级的lambda语法,例如Haskell \x -> f x + g x
或C#x => f(x) + g(x);
2.每当我有一个需要采取一些抽象行为的函数时,比如map
,或者each
,或者on_clicked
,我会感谢传递lambda而不是命名函数的能力,因为它更容易.最终,你不再认为它们有点特别 - 它们与数组的文字语法一样令人兴奋而不是empty().append(1).append(2).append(3)
.只是该语言的另一个有用的部分.
1:在简并的情况下,你真的只需要八条指令:+-<>[].,
. <>
沿阵列移动一个虚构的"指针"; +-
递增和递减当前单元格中的整数; []
执行非零循环; 并.,
做输入和输出.其实,你真的只需要只是一个指令,如subleq a b c
(减去a
从b
并跳转到c
如果结果小于或等于零).
2:我从未真正使用过C#,所以如果语法错误,请随意纠正.
好吧,在Ruby中,通常不会使用lambda或proc,因为块大致相同并且更方便.
用途是无限的,但我们可以列出一些典型案例.人们通常将功能视为执行一部分处理的较低级别的块,可能通常编写并制作成库.
但通常人们想要自动化包装器并提供自定义库.想象一下,使HTTP或HTTPS连接或直接TCP连接的函数将I/O提供给其客户端,然后关闭连接.或者也许只是用普通的旧文件做同样的事情.
所以在Ruby中我们将函数放在一个库中并让它为用户提供一个块...客户端..."调用者"来编写他的应用程序逻辑.
在另一种语言中,这必须使用实现接口的类或函数指针来完成.Ruby有块,但它们都是lambda样式设计模式的例子.
小智 6
它归结为风格.Lambdas是一种陈述式的风格,方法是势在必行的风格.考虑一下:
Lambda,blocks,procs都是不同类型的闭包.现在的问题是,何时以及为何使用匿名闭包.我可以回答 - 至少在红宝石中!
闭包包含调用它们的词汇上下文.如果从方法中调用方法,则不会获得调用方法的上下文.这是由于对象链存储在AST中的方式.
另一方面,闭包(lambda)可以通过方法与词汇上下文一起传递,允许进行惰性求值.
lambdas自然也适用于递归和枚举.
1)这只是一个方便.您不需要为某些块命名
special_sort(array, :compare_proc => lambda { |left, right| left.special_param <=> right.special_param }
Run Code Online (Sandbox Code Playgroud)
(想象一下,如果你必须命名所有这些块)
2)#lambda通常用于创建clojures:
def generate_multiple_proc(cofactor)
lambda { |element| element * cofactor }
end
[1, 2, 3, 4].map(&generate_multiple_proc(2)) # => [2, 3, 5, 8]
[1, 2, 3, 4].map(&generate_multiple_proc(3)) # => [3, 6, 9, 12]
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
8192 次 |
最近记录: |