Ruby 手册 | 18 - 符号 Symbol

219 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第18天,点击查看活动详情

一、符号 Symbol

Ruby 中的符号类型是一个非常特别的类型,Java Python 中都没有符号这种数据类型。Ruby 中的符号概念简单,使用起来也很方便,并且在 Ruby 代码中使用非常广泛。

符号 Symbol 类的实例,通常只需要使用冒号加上一个标识符即可创建一个符号。例如 :sym:tony 以及 :12 都是符号类型数据,使用引号包含的字符串只要有 : 也是符号类型数据

:"stark"
:"123abcd"

符号跟字符串很像,但不同于字符串,相同内容的字符串可能是两个不同的对象,但是相同标识符号表示的符号类型都是不同的变量指向的同一个实例,也就是说符号是引用类型数据。可以通过 object_id 方法来获取对象的内存地址。

a = "stark"
b = "stark"
puts a.object_id
puts b.object_id

a_sy = :a
b_sy = :a
puts a_sy.object_id
puts b_sy.object_id

执行上述代码,输出结果如下:

70268315957700
70268315957680
765468
765468

字符串 a 和字符串 b 的内容是相同的,但是两个字符串对象的内存地址是不同的,说明这是两个实例;而内容相同的两个符号变量 a_sy 和 b_sy 内容相同并且内存地址也相同,说明是两个不同的变量指向同一个符号类型的实例。

二、符号和字符串的区别和相互转换

字符串和符号之间的相互转换

符号和字符串之间是可以互相转换的,使用的方法分别为 to_s 和 to_sym。

a = :"stark"
b = "tony"

puts a.class
puts a.to_s
puts (a.to_s).class

puts b.class
puts b.to_sym
puts (b.to_sym).class

执行上述代码,输出结果如下:

Symbol
stark
String
String
tony
Symbol

字符串和符号之间的区别

符号与字符串相比较,优势在于符号消耗的内容存更少,因为额每一个字符串都是一个对象,一个字符串出现一次就会创建一个 String 对象,所以字符串的内存开销很大,而符号是引用数据类型,相同内容的符号只会存在一个实例。

符号通常用于需要保证名称和变量一一对应的情况,通常来讲,如果变量类型在 String 和 Symbol 之间选择可以参考以下标准:

  • 如果使用字符串的内容,这个内容可能会发生变化,则使用 String
  • 如果使用固定的名字或者是标识符,则使用符号 Symbol

实际开发中枚举值、关键字(散列表关键字、方法的参数)等都是使用符号 Symbol 类型。

比如定义一个枚举值

[:spring, :summer, :autumn, :winter]

如果使用字符串显然会更多内存。

并且符号也常作为散列表的键

info = {:name => "stark", :age => "30"}

如果使用字符串作为主键,每次在使用使用时消耗的内存较多

定义属性时也常使用符号

class Car
    attr :brand, :color
end