Ruby Quick Start (4) -- Array, String, Closure

2016-10-22 10:04:28来源:作者:Yilin's blog人点击

《Ruby语言入门教程v1.0》笔记(4)

第八章 Ruby中的数组、字符串、闭包 1. Ruby中的数组 1.1 建立数组 arr1 = []arr2 = Array.newarr3 = ['4 ','5 ','6 ']print arr1, "/n"print arr2, "/n"print arr3, "/n" 1.2 访问数组元素 arr = [3,4,5,6,7,8,9]puts arr[0]# 3puts arr.first # 3puts arr[arr.length-1]# 9puts arr[arr.size-1]# 9puts arr.last # 9puts arr[-1]# 9puts arr[-2]# 8print arr[1..3] ,"/n"# 456print arr[-3,2] ,"/n"# 78

数组的索引从 0开始,一直到数组的长度减去 1;

负数表示从数组末尾开始的索引;

用一对数字来索引数组,第一个数字表示开始位置,第二数字表示从开始位置起的元素数目。

1.3 增加、删除数组元素

Ruby 的数组大小是动态的,你能够随时增加、删除数组元素。

print arr.join(", "), "/n"意思是:将数组 arr转换成字符串输出,用” ,“隔开每个元素,并且换行。

arr = [4,5,6]print arr.join(", "),"/n"# 4, 5, 6arr[4] ="m"# 把 4 号索引位置元素赋值为"m"print arr.join(", "),"/n"# 4, 5, 6, , mprint arr[3],"/n"# 打印 3 号索引位置元素 #nilarr.delete_at(3)# 删除 3 号索引位置元素print arr.join(", "),"/n"# 4, 5, 6, marr[2] = ["a","b","c"]# 把 2 号索引位置元素赋值为["a","b","c"]print arr.join(", "),"/n"# 4, 5, a, b, c, mprint arr[2],"/n"# 打印 2 号索引位置元素 #abcarr[0..1] = [7,"h","b"]# 把 0..1 号元素替换为 7, "h", "b"print arr.join(", "),"/n"# 7, h, b, a, b, c, marr.push("b")# 加入元素"b"print arr.join(", "),"/n"# 7, h, b, a, b, c, m, barr.delete(["a","b","c"])# 删除元素["a","b","c"]print arr.join(", "),"/n"# 7, h, b, m, barr.delete("b")# 删除所有元素"b"print arr.join(", "),"/n"# 7, h, marr.insert(3,"d")# 在 3 号索引位置插入元素"d"print arr.join(", "),"/n"# 7, h, m, darr << "f"<<2# 加入元素"f";加入元素 2print arr.join(", "),"/n"# 7, h, m, d, f, 2arr.pop # 删除尾元素print arr.join(", "),"/n"# 7, h, m, d, farr.shift # 删除首元素print arr.join(", "),"/n"# h, m, d, farr.clear # 清空数组 arrprint arr.join(", "),"/n"# 1.4 数组运算 aaaa = [" aa ",4,5," bb "]bbbb = [4,1,3,2,5]print aaaa + bbbb, "/n"# aa 45 bb 41325print aaaa * 2,"/n"# aa 45 bb aa 45 bbprint bbbb - aaaa, "/n"# 132# 并运算;交运算print aaaa | bbbb, "/n"# aa 45 bb 132print aaaa & bbbb, "/n"# 45# 排序;倒置print bbbb.sort, "/n"# 12345print aaaa.reverse, "/n"# bb 54 aa 2. Ruby中的字符串 2.1 字符串的创建

字符串是 String类的对象,一般使用字面值来创建。

str1 = 'this is str1'str2 = "this is str2"str3 = %q/this is str3/str4 = %Q/this is str4/str5 = << OK_strHereis string document, str5 line one; line two; line three.OKOK_strputs str3puts str4puts str5

输出结果:

this is str3

this is str4

Here is string document, str5

line one;

line two;

line three.

OK

%q用来生成单引号字符串; %Q用来生成双引号字符串。

%q或者 %Q后面跟着的是分隔符,可以是配对的 ! !; / /; < >; ( ); [ ]; { };等等。

str5是一个字符串文档,从 <<和文档结束符的下一行开始,直到遇到一个放置在行首的文档结束符,结束整个字符串文档。

一个数组可以用 join方法转换成字符串, join()内的参数也是一个字符串,用来分隔数组的每个元素,例如: arr.join(", ")。

2.2 字符串操作

字符串既然是 String类的对象, String类的方法你都可以使用在字符串变量上, String类的方法非常多,下面略举几例。

str = ' this'+" is"str += " you"str << " string"<<" ."puts str*2# this is you string . this is you string .puts str[-12,12]# you string . 2.3 字符串转义

双引号括起来的字符串会有转义,例如:” /n“ 表示换行。还有一些其它的转义符号,比如制表符之类。

str = " this is you string ."puts str * 2# this is you string . this is you string .str = " this is you string ./n"puts str*2# this is you string .this is you string .str = " /tthis is you string ."puts str # this is you string .str = ' this/'s you string ./n'puts str # this's you string ./n

单引号括起来的字符串并不会对字符串作任何解释,你看到的是什么便是什么,有一个例外:单引号字符串里的 单引号需要转义。

2.4 字符串内嵌表达式

在双引号扩起来的字符串中, 不仅可以使用各种转义符, 而且可以放置任意的Ruby 表达式在 #{ }之中,这些表达式在使用这个字符串的时候被计算出值,然后放入字符串。

defhello(name)" Welcome, #{name}!"endputs hello("Yilin")# Welcome, Yilin !puts hello("Ben")# Welcome, Ben !

字符串内嵌表达式,使得你能够更加灵活地组织代码,表现出更强、更多的动态特性。

3. Ruby中的正则表达式(暂时略过)

Ruby是一种强烈而灵活地支持正则表达式的语言。

正则表达式强大,但是枯燥。有一个办法,就是 等你需要用的时候再来学习。

4. 迭代器、代码块、闭包 (1..9).each {|i| print iifi <7}

迭代器 each是数组类的一个方法;大括号 { }里的代码是代码块,简称 块。

你可以用大括号 { }将代码组织成块,也可以用 do...end将代码组织成块。

大括号 { }的优先级高于 do...end。

我们来写一个最简单的块:

defone_blockyieldyieldyieldendone_block { puts "This is a block. "}

输出结果:

This is a block.

This is a block.

This is a block.

从上面的程序可以看到调用一个块要用关键字 yield。每一次 yield,块就被调用一次。

yield还可以带参数调用块:

defone_blockfornumin1..3yield(num)endendone_block do|i| puts "This is block#{i}. "end

输出结果:

This is block 1.

This is block 2.

This is block 3.

一个块可以接收 yield传来的参数,还可以将结果返回给调用它的方法。

到目前为止,实在看不出使用代码块的优势,可以把块里的代码直接写在方法中。

如果我们还没有决定块里写什么代码, 又或者块里的代码会随着不同的情形而变化, 那么就看出代码块的灵活性了。

defdo_somethingyieldenddo_something do (1..9).each {|i| print iifi<5} putsenddo_something do3.times { print"Hi!"} putsend

输出结果:

1234

Hi!Hi!Hi!

其中的技巧:先写出方法的大致框架,调用方法的时候才告诉方法要做什么。

虽然与代码块有关联的方法不都是迭代器,但是, 迭代器确实是一个与代码块有关联的方法。让我们为数组类增加一个迭代器 one_by_one:

classArraydefone_by_oneforiin0...sizeyield(self[i])end putsendendarr = [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,

代码块是一段代码,相当于一个 匿名方法,被调用它的方法所调用。

如果我们不仅仅想调用代码块,还想 把代码块作为参数传递给其它方法,就要使用 闭包了。

闭包也是一段代码,一个代码块,而且 能够共享其它方法的局部变量。

defmethod(pr) puts pr.call(7)endoneProc = proc{|k| k *= 3}method(oneProc)

输出结果:

21

来看一个闭包共享其它方法局部变量的例子:

defmethod(n)returnproc{|i| n += i }endoneProc = method(3)puts oneProc.call(9)# 12puts oneProc.call(5)# 17, 注意不是8!

方法 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作为自己的返回值输出。

最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台