Ruby中String和Symbol的区别

String(字符串)

"iPhone"
'iPhone'

Symbol(符号)

:iPhone

区别

  1. 类型不同
   $ irb --simple-prompt
   >> "iPhone".class
   => String
   >> :iPhone.class
   => Symbol
  1. 字符串可变(mutable),符号不可变(immutable)
   $ irb --simple-prompt
   >> s = 'iphone'
   => "iphone"
   >> s.object_id
   => 70344182559760
   >> s[1] = 'P'
   => "P"
   >> s
   => "iPhone"
   >> s.object_id
   => 70344182559760
  1. 同名符号是相同对象,而相同字符串则是不同对象
   $ irb --simple-prompt
   >> "iPhone".object_id
   => 70182408206300
   >> 'iPhone'.object_id
   => 70182408188520
   >> :iPhone.object_id
   => 1168028
   >> :iPhone.object_id
   => 1168028

总结

基于以上3点区别,在作为常量(例如hash key)等场合,使用符号占用更少的内存,更高效。因为符号与字符串是不同类型,符号对象就不能使用字符串方法,例如#upcase, #split等。两者可以通过to_sto_sym方法互相转换。

$ irb --simple-prompt
>> "iPhone".class
=> String
>> :iPhone.class
=> Symbol
>> "iPhone".to_sym.class
=> Symbol
>> :iPhone.to_s.class
=> String

当用作hash key时,两者是不等价的(*其实很好理解,因为类型就不同*),不能混用。

$ irb --simple-prompt
>> a = {:name => 'ruby', :version => '2.4.0'}
=> {:name=>"ruby", :version=>"2.4.0"}
>> a.each do |k, v|
?> puts "#{k}: #{k.class}"
>> end
name: Symbol
version: Symbol
=> {:name=>"ruby", :version=>"2.4.0"}
>> b = {"name" => "ruby", "version" => "2.4.0"}
=> {"name"=>"ruby", "version"=>"2.4.0"}
>> b.each do |k, v|
?> puts "#{k}: #{k.class}"
>> end
name: String
version: String
=> {"name"=>"ruby", "version"=>"2.4.0"}

Contents