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'
}

你可能感兴趣的:(ruby中symbol 和 string)