ruby中symbol 和 string
1. 了解symbol
-
symbol是什么
符号(symbol)和字符串很相似,符号也是对象,一般作为名称标签来使用,用来表示方法等对象的名称,另外符号和字符串可以相互转换 -
如何创建Symbol对象
创建一个 Symbol 对象的方法是在名字或者字符串前面加上冒号:
#创建symbol对象
:test1
:'test3'
-
symbol特征
名字相同,则Symbol 相同。
#在ruby中每一个对象都有唯一对象标识符
#可以通过object_id方法来获得一个对象的标识符
'test1'.object_id
=>70201737198340
'test1'.object_id
=>70201752605900
'test1'.object_id
=>70201752351880
:test2.object_id
=>8869148
:test2.object_id
=>8869148
:'test2'.object_id
=>8869148
可以看到前三行代码中('test1')的object_id得到的结果都是不同的,说明字符串'test1'都是不同的对象
后三行的代码中(:test2或者:'test2')的object_id得到的结果都是相同的值,说明:test2或者:'test2'都是同一个Symbol对象
名字相同,则Symbol 相同。
每个String对象都是不同的,即使他们是一个名字(包含了相同的字符串内容),而对于Symbol对象,一个名字(相同的字符串内容)唯一确定一个Symbol对象
class Test
puts :Test.object_id
Test = 10
puts :Test.object_id
def Test
puts :Test.object_id
end
end
Test.new.Test
=>224298
=>224298
=>224298
Symbol不可以像其他变量一样对它进行赋值运算。比如这样的写法是错误的:myname = "Tom"。 相反Symbol可以作为值赋给其他变量比如mystring = :myname。
所有 Symbol 对象存放在 Ruby 内部的符号表中,可以通过类方法 Symbol.all_symbols 得到当前 Ruby 程序中定义的所有 Symbol 对象,该方法返回一个 Symbol 对象数组
2.symbol和string的区别
-
方法
String 类有非常多的方法,包括 Mixed-in 方法(Ruby中一个类通过 include 其他模块而得到的方法,实现多重继承的效果)、类方法和实例方法;而 Symbol 类只有一个类方法 all_symbols 和7个实例方法。
例如,可以通过 []= 方法改变 string 的内容,而 symbol 则不行:
#[]= 方法比较
irb(main):001:0> s="test"
=> "test"
irb(main):002:0> s[0]='1'
=> "1"
irb(main):003:0> puts s
1est
=> nil
irb(main):004:0> sym=:test
=> :test
irb(main):005:0> sym[0]=1
NoMethodError: undefined method `[]=' for :test:Symbol
from (irb):5
irb(main):006:0>
-
内存 效率
Symbol比字符串更加节省内存,提高运行效率
因为对一个字符串对象的多次引用会生成不同的字符串的对象,而对一个Symbol对象的多次引用用的是同一个对象(上面的对象标识符说明了一切) -
转换
.to_sym (string=>symbol)
.to_s (symbol=>string)
var1 = "test".to_sym #=>:test
var1 = :test.to_s #=>"test"
3. 使用symbol
1.选择标准
String 还是 Symbol 的选择标准:
如果使用字符串的内容,这个内容可能会变化,使用 String
如果使用固定的名字或者说是标识符,使用 Symbol
那么什么时候我们会用到名字呢?很多时候都会,比如枚举值、关键字(哈希表关键字、方法的参数)等等
2. 哈希表中的key
下面这个哈希表表示按城市分类的一些机器的集合。
一个使用string作为key的哈希表例子
hosts{
'beijing' => 'machine1',
'shanghai' => 'machine2',
'guangzhou' => 'machine3',
'tianjin' => 'machine4',
'shenzhen' => 'machine5'
}
如果要引用 beijing 的机器,使用 hosts['beijing'] 。但如果我们程序中要频繁引用哈希表中 value ,这样就不大好了,因为 Ruby 对每一次字符串引用都会生成一个 String 对象,累积下来这个开销是相当大的。
我们完全可以使用 Symbol ,因为对于这些 key 来讲,我们用的就是名字而已,例如下面hosts[:beijing]
使用 Symbol 作为 key
hosts = {
:beijing => 'machine1',
:shanghai => 'machine2',
:guangzhou => 'machine3',
:tianjin => 'machine4',
:shenzhen => 'machine5'
}