a = %w( ant bee cat dog elk ) # create an array a.each { |animal| puts animal } # iterate over the contents
5.times { print "*" } 3.upto(6) {|i| print i } ('a'..'e').each {|char| print char } |
::
双冒号
域作用符,将模块(类)与它的常量隔开
类重复定义,只是增加方法
在 Ruby 中 Symbol 表示“名字”,比如字符串的名字,标识符的名字,创建一个 Symbol 对象的方法是在名字或者字符串前面加上冒号:
在 Ruby 中每一个对象都有唯一的对象标识符(Object Identifier),可以通过 object_id 方法来得到一个对象的标识符。例子如下:
2 327458
3 irb(main): 002 : 0 > puts :foo.object_id
4 327458
5 irb(main): 003 : 0 > puts : " foo " .object_id
6 327458
7 irb(main): 004 : 0 > puts " foo " .object_id
8 24303850
9 irb(main): 005 : 0 > puts " foo " .object_id
10 24300010
11 irb(main): 006 : 0 > puts " foo " .object_id
12 24296170
前三行语句中的 :foo (或者 :"foo")都是同一个 Symbol 对象,其 object id 为327458,而后三行中的字符串”foo”都是不同的对象,其 object id 依次为24303850、24300010、24296170。
可见,每个 String 对象都是不同的,即便他们包含了相同的字符串内容;而对于 Symbol 对象,一个名字(字符串内容)唯一确定一个 Symbol 对象(Symbol 对象的字符串中不能含有’\0’字符)。
除了可以采用一般的字符串,还可以使用操作符(例如+, -, *, /),变量,常量,方法甚至类的名字来创建 Symbol 对象,例如:+就是一个合法的 Symbol 。实际上,在 Ruby 内部操作符、变量等名字本身就是作为 Symbol 处理的,例如当你定义一个实例变量时, Ruby 会自动创建一个 Symbol 对象,例如 @test 对应为 :@test 。
2
3 class Test
4 attr_accessor :test
5 end
Symbol 对象和 String 对象是完全不同的东西,对象标识符很明确的说明了这一点。
使用 to_s 或 id2name 方法将 Symbol 转化为一个 String 对象:
1
2
3
4
5
6
|
irb(main):
001
:
0
>
:test
.id2name
=>
"test"
irb(main):
002
:
0
>
:test
.to_s
=>
"test"
irb(main):
003
:
0
> :
"I am a boy"
.to_s
=>
"I am a boy"
|
注意,每个 String 对象都是唯一的,因此对一个 Symbol 调用多次将产生多个 String 对象。
除了在字符串前面加冒号,还可以使用 to_sym 或 intern 方法将 String 转化为 Symbol ,如果该 Symbol 已经存在,则直接返回。
2 => :test
3 irb(main): 002 : 0 > var2 = " test " .intern
4 => :test
5 irb(main): 003 : 0 > var1 == var2
6 => true
7 irb(main): 004 : 0 >
正如前边提到的, Ruby 内部一直在使用 Symbol ,比如 Ruby 程序中的各种名字,Symbol本质上是 Ruby 符号表中的东西。使用 Symbol 处理名字可以降低 Ruby 内存消耗,提高执行速度,这点我们在下一篇文章中会看到。
那么 Symbol 对我们有什么用呢?当然也是内存。使用 String 的开销太大了,因为每一个String 都是一个对象。想想前边的例子,一个字符串每出现一次 Ruby 就会创建一个 String 对象。
通常来讲,当你面临 String 还是 Symbol 的选择时,可以参考以下标准:
- 如果使用字符串的内容,这个内容可能会变化,使用 String
- 如果使用固定的名字或者说是标识符,使用 Symbol
那么什么时候我们会用到名字呢?很多时候都会,比如枚举值、关键字(哈希表关键字、方法的参数)等等
哈希表是 Symbol 应用最为广泛的地方。在ruby中,哈希和数组类似,一个哈希表是一系列 key/value 对的集合,只不过它的 key 取值范围更广泛,可以是任何对象,比如正则表达式。
但通常我们都会取有意义的 key ,比如 String、Symbol 。
下面这个哈希表表示按城市分类的一些机器的集合:
2 ' beijing ' => ' machine1 ' ,
3 ' shanghai ' => ' machine2 ' ,
4 ' guangzhou ' => ' machine3 ' ,
5 ' tianjin ' => ' machine4 ' ,
6 ' shenzhen ' => ' machine5 '
7 }
如果要引用 beijing 的机器,使用 hosts['beijing'] 。但如果我们程序中要频繁引用哈希表中 value ,这样就不大好了,因为 Ruby 对每一次字符串引用都会生成一个 String 对象,
累积下来这个开销是相当大的,我们可以使用 Symbol 作为 key:
1
|
hosts =
{
:beijing
=>
'machine1'
,
:shanghai
=>
'machine2'
,
:guangzhou
=>
'machine3'
,
:tianjin
=>
'machine4'
,
:shenzhen
=>
'machine5'
}
|
通常我们定义的函数的参数的个数和顺序是写死的,调用函数的时候要确保参数的个数、顺序匹配,有时候这样很不方便,使用哈希参数可以解决这个问题。