深入理解Ruby中的block概念
Ruby 里的 block一般翻译成代码块,block 刚开始看上去有点奇怪,因为很多语言里面没有这样的东西。事实上它还不错。 First-class function 和 Higher-order function 是函数式编程语言里面的概念,听起来好像很高端的样子,其实很很简单的。 First-class functions 是指在某些语言里,函数是一等公民,可以把函数当做参数传递, greet = (name) -> return -> console.log "Hello,#{name}" greetToMike = greet("Mike") greetToMike() # => 输出 "Hello,Mike" a = greetToMike a() # => 输出 "Hello,Mike" 在上面的第四行里,greet("Mike") 返回了一个函数,所以第五行里才可以调用 greetToMike()输出"Hello,Mike"。第六行把一个函数赋值给了a,所以第七行就可以调用这个函数了。 higher-order function 一般翻译成高阶函数,是指接受函数做参数或者返回函数的函数。 a = [ "a","b","c","d" ] a.map((x) -> x + '!') #=> ["a!","b!","c!","d!"] 上面例子里 map 就接受了一个匿名函数作为参数。Array.prototype里的很多方法,比如reduce,filter,every,some 等等都是高阶函数,因为他们都接受函数作为参数。 高阶函数非常强大,表达力很强,可以避免大量重复代码。总的来说,它就是个好东西。 先来看一组 Ruby 和 CoffeeScript 代码的对比。 a = [ "a","d" ] a.map { |x| x + "!" } # => ["a!","d!"] a.reduce { |acc,x| acc + x} # => "abcd" a = [ "a","d" ] a.map((x) -> x + '!') # => ["a!","d!"] a.reduce((acc,x) -> acc + x) # => "abcd" 这两组代码真的看起来超级像。我觉得这也暴露了 Ruby 的 block 的本质:高阶函数的函数参数的变体。 JavaScript 里面的map 函数接受一个函数作为参数,但是 Ruby 里的 map 却接受一个 其实 matz 早在一本书里《松本行弘的程序世界》里说了: 复制代码 代码如下: 最终来看,块到底是什么?
... 块也可以看作只是高阶函数的一种特殊形式的语法。 ... 高阶函数和块的本质一样 ... 在 Ruby 里,函数不是一等公民,没有 first-class functions。但是在 Ruby 我发现在 Ruby 里使用 block 时,几乎所有的情况下都可以用 JavaScript Enumerable 模块里的所有方法都是典型的例子。事实上确实存在 JavaScript 版 除了语法上看上去有点不同外,有非常重要的两点。 在 block 里面可以用 break,next 等等这些在一般的循环里才有的控制流操作,这些 从这一点来看 block 确实还不错的。 Ruby 里一个方法只能接受一个 block 作为参数,大概就是类似于只有一个函数参数的高阶 嗯,这篇文章看起来有点太长了,所以我不打算写下去了。其实还有一些重要的地方没说。比如 name = "mike" def greet puts "hello,#{name}" end hello # => in `greet': undefined local variable or method `name' for main:Object (NameError) 但是用 block 就可以了 name = "mike" define_method(:greet) do puts "hello,#{name}" end greet # => "hello,mike" 用 JavaScript 就根本不存在问题。 name = "mike" greet = -> console.log "hello,#{name}" greet() # => "hello,mike" 同理还有class 和 module 关键字都会创建新的作用域而在里面接触不到外面的变量, 还有那个 proc 和 lambda 的区别。其实我一直不理解为什么会有人不用lambda def hello (1..10).each { |e| return e} return "hello" end hello # => 1 这感觉真是有点悲催。 说了这么多,就是因为在 Ruby 里面函数不是一等公民,又想获得函数式编程的便利。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |