s="hello"
puts s.object_id你会发现他们的object_id是不同的,这和类似Java这样的语言处理方式是不同的,Java中的字符串是不可变对象,所以如果你在Java中定义两个相同内容的字符串,他们在内容中实际上是占用同一块内存地址。
s2="hello"
puts s2.object_id
那么Symbol的作用就是唯一标识一个名字,它占用唯一的一个内存地址。Symbol通过在一个唯一的标识符或者字符串前加冒号(:)来定义:
:symbol #定义一个Symbol
:"symbol" # 另一种方式
:'another long symbol' # 如果Symbol对象包含空格,可以用引号包含
s = "string"
sym = :"#{s}" # Symbol对象:string
就像String中使用%q和%Q定义字符串的方式,你也可以用%s加上任意的边界符号来定义一个Symbol。
%s[hello] # 等同于 :hello
Symbol经常用于方法的反射机制,比如我们经常需要判断一个对象是否有each方法:
o.respond_to? :each
下面这个例子用于判断一个对象是否包含一个特定的方法,如果有,就调用它:
name = :size
if o.respond_to? name
o.send(name)
end
你可以通过intern或者to_sym将一个字符串转换为Symbol,反过来你可以使用to_s或者id2name方法将Symbol转换为字符串:
str = "string" # 定义一个字符串最后我们来总结一下,拥有相同内容的字符串是不同的对象,但是拥有相同内容的字符串转换成的Symbol是一样的,不同的Symbol内容总是不同的。
sym = str.intern # 转换为 symbol
sym = str.to_sym # 另一种转换方法
str = sym.to_s # 在转换回字符串
str = sym.id2name # 另一个转换成字符串的方法
如果你的程序中用到了字符串,而这个字符串可能表示的是一个唯一的内容,你应该考虑使用Symbol,所以如果你使用字典对象,那么最好用Symbol作为元素的“键”。
在Ruby1.9中增加了一系列String对象中的方法,比如length,size等等,你可以使用这种方式,实现类似不可变字符串的功能。
No comments:
Post a Comment