- 浏览: 84719 次
- 性别:
-
最近访客 更多访客>>
最新评论
-
Bernice_liu:
谢谢分享,受益匪浅,适合我——初学者
Ruby语言中文教程all in one -
何枫abc:
怎么感觉Ruby有点像C!!!
3.5 标识名和变量的作用域 3.6 类库 3.7 数据类型 -
何枫abc:
谢谢了!!!你写的很好,现在我正在学Ruby!!!
第二章 运行环境 -
yangzhihuan:
正想知道ruby是怎么样生成像javadoc那样的文档,多谢了 ...
3.1 注释与分行 -
whisper:
从lambda演算的角度说我们并不关心一个东西到底是什么,而只 ...
变量一定要有类型吗(一)
先看一句代码:
ruby 代码
- (1..9).each {|i| print i if i<7} # =>123456
迭代器each 是数组类的一个方法;大括号{ }里的代码是代码块,简称块。你可以用大括号{ }将代码组织成块,也可以用 do…end将代码组织成块。大括号{ }的优先级高于do…end。
我们来写一个最简单的块;
- #E8.4-1.rb
- def one_block
- yield
- yield
- yield
- end
- one_block { puts "This is a block. " }
运行结果:
This is a block.
This is a block.
This is a block.
从程序 E8.4-1.rb 可以看到调用一个块要用关键字yield。每一次 yield,块就被调用一次。yield 还可以带参数调用块,看程序 E8.4-2.rb :
ruby 代码
- #E8.4-2.rb
- def one_block
- for num in 1..3
- yield(num)
- end
- end
- one_block do |i|
- puts "This is block #{i}. "
- end
运行结果:
This is block 1.
This is block 2.
This is block 3.
一个块可以接收yield 传来的参数,还可以将结果返回给调用它的方法。到目前为止,实在看不出使用代码块的优势,可以把块里的代码直接写在方法中。如果我们还没有决定块里写什么代码,又或者块里的代码会随着不同的情形而变化,那么就看出代码块的灵活性了。
ruby 代码
- #E8.4-3.rb
- def do_something
- yield
- end
- do_something do
- (1..9).each {|i| print i if i<5}
- puts
- end
- do_something do
- 3.times { print "Hi!" }
- puts
- end
运行结果:
>ruby E8.4-3.rb
1234
Hi!Hi!Hi!
>Exit code: 0
两次使用方法do_something,第一次do_something遇到yield,调用了代码块{ 输出1..9中小于5的数 } ;在程序的另一处do_something的时候,我们希望做一些不同的事,所以我们写了一个不同于前一次的代码块{ 输出3次“Hi!”}。
这是一个简单的例子,但是你能发现其中的技巧:先写出方法的大致框架,调用方法的时候才告诉方法要作什么。
虽然与代码块有关联的方法不都是迭代器,但是,迭代器确实是一个与代码块有关联的方法。让我们为数组类增加一个迭代器 one_by_one;
- #E8.4-6.rb
- class Array
- def one_by_one
- for i in 0...size
- yield(self[i] )
- end
- puts
- end
- end
- arr = [1,3,5,7,9]
- arr.one_by_one {|k| print k , ", "} # => 1, 3, 5, 7, 9,
- arr.one_by_one {|h| print h*h, ", "} # => 1, 9, 25, 49, 81,
代码块是一段代码,相当于一个匿名方法,被调用它的方法所调用。如果我们不仅仅想调用代码块,还想把代码块作为参数传递给其它方法,就要使用闭包了。闭包也是一段代码,一个代码块,而且能够共享其它方法的局部变量。
闭包既然是一段代码,也就有自己的状态,属性,作用范围,也就是一个可以通过变量引用的对象,我们称之为过程对象。一个过程对象用Proc.new创建,用call方法来调用。
先看一个闭包作为参数传递给其它方法的例子;
- #E8.4-4.rb
- def method(pr)
- puts pr.call(7)
- end
- oneProc=Proc.new{|k| k *=3 }
- method(oneProc)
运行结果:
>ruby E8.4-4.rb
21
>Exit code: 0
再看一个闭包共享其它方法局部变量的例子;
- #E8.4-5.rb
- def method(n)
- return Proc.new{|i| n +=i }
- end
- oneProc=method(3)
- puts oneProc.call(9) # => 12
- puts oneProc.call(5) # => 17
方法method 返回一个Proc对象,这个对象引用了这个函数的参数:n 。即使 n这个参数在闭包被调用时已经不在自己的作用域里了,这个闭包还是可以访问 n这个参数,并且和方法method 共同拥有变量 n 。开始的时候,方法method 的变量 n是3;oneProc.call(9)的时候,oneProc更新了变量 n,把n=12传回给方法method;oneProc.call(5)的时候,oneProc取出方法method的变量 n=12,更新为n=17,传回给方法method的同时,也把n=17作为自己的返回值输出。
完整阅读,请看我写的 Ruby语言中文教程all in one
发表评论
-
8.3 正则表达式
2007-02-13 06:13 1602一本入门小书,不想涉及正则表达式,但是正则表达式与Ruby语言 ... -
8.2 再说字符串
2007-02-13 06:07 1408一. 生成一个字符串 字 ... -
8.1 再说数组
2007-02-13 06:03 1519一. 建立一个数组 ruby 代码 #E8.1- ... -
7.4 require 和 load
2007-02-13 05:59 1375程序 E7.3-1.rb中先写了Me模块,然后include ... -
7.3 糅和(Mix-in) 与多重继承
2007-02-13 05:55 1833糅和,也译作混合插入,也许就称作 Mix-in 比较合适。 现 ... -
7.1 模块 7.2 命名空间
2007-02-13 05:50 22597.1 模块 我们常常把许 ... -
6.5 访问控制
2007-02-13 05:43 1238在Ruby里,要读取,或是改变对象的属性,唯一的途径是调用对象 ... -
6.4 单例方法
2007-02-13 05:16 1060同一份设计蓝图(类),不同的实例对象,可以表现出不同的行为特征 ... -
6.3 实例变量、类变量、类方法
2007-02-13 05:28 2305学习编程的过程,就是深化理解变量的过程。在面向对象编程中也不例 ... -
6.2 增强父类方法
2007-02-13 04:39 1067如果我们只是想增强父类的方法,而不是完全地替代它,就可以用关键 ... -
6.1 重载?重写
2007-02-13 04:11 1944在Java 中,重载(overload)和重写(overrid ... -
5.5 一些编码建议
2007-02-13 03:37 1186这里不是 Ruby语言的编 ... -
5.4 蓝图可以改变吗? ——动态语言
2007-02-13 03:28 791Ruby 是动态语言,你可以改变 Ruby 程序的结构,功能, ... -
5.3 详解变量—— 动态类型
2007-02-13 03:22 1230变量是什么?变量有哪些特征呢?学习编程的过程,就是深化理解变量 ... -
5.1 为什么是Ruby? 5.2 Ruby会长久么?
2007-02-13 03:16 10505.1 为什么是Ruby? 现 ... -
4.5 多态
2007-02-13 03:07 815不同的子类继承一个父 ... -
4.4 继承
2007-02-13 03:04 854如果我们要写一个学生 ... -
4.3 封装
2007-02-13 02:53 945让我们来定义一个类,类名是Person,类名首字母要大写;属性 ... -
4.1 两种思维方式 4.2 对象
2007-02-13 02:47 9584.1 两种思维方式 人们 ... -
3.11 一个综合小练习
2007-02-13 02:05 1042还是求50以内的素数,尽可能地用到本章更多的语法,看程序 E3 ...
相关推荐
- **闭包**:迭代器通常是闭包的形式,以便能够保存内部状态。 ##### 7.2 泛型for的语义 - **定义**:`for key, value in iterator do`,其中`iterator`是一个迭代器函数。 - **工作原理**:每次循环都会调用迭代器...
5.3迭代器和可枚举对象130 5.4代码块140 5.5改变控制流146 5.6异常和异常处理154 5.7BEGIN和END165 5.8线程、纤程和连续体166 第6章方法、PROC、LAMBDA和闭包175 6.1定义简单方法177 6.2方法名180...
2.10 代码块及缩进对齐 2.11 if语句 2.12 while循环 2.13 for循环和range()内建函数 2.14 列表解析 2.15 文件和内建函数open()、file() 2.16 错误和异常 2.17 函数 ...
2.10 代码块及缩进对齐 2.11 if语句 2.12 while循环 2.13 for循环和range()内建函数 2.14 列表解析 2.15 文件和内建函数open()、file() 2.16 错误和异常 2.17 函数 ...
4.2 局部变量与代码块(block)......19 4.3 控制结构语句...........20 Programming in Lua iv Copyright ® 2005, Translation Team, www.luachina.net 4.4 break和return语句......23 第5章函数......24 ...