• Ruby中的symbol ":" 【一】


    在 Ruby 中 Symbol 表示“名字”,比如字符串的名字,标识符的名字,创建一个 Symbol 对象的方法是在名字或者字符串前面加上冒号:

    在 Ruby 中每一个对象都有唯一的对象标识符(Object Identifier),可以通过 object_id 方法来得到一个对象的标识符。例子如下:

    1irb(main):001:0> puts :foo.object_id
    2327458
    3irb(main):002:0> puts :foo.object_id
    4327458
    5irb(main):003:0> puts :"foo".object_id
    6327458
    7irb(main):004:0> puts "foo".object_id
    824303850
    9irb(main):005:0> puts "foo".object_id
    1024300010
    11irb(main):006:0> puts "foo".object_id
    1224296170

    前三行语句中的 :foo (或者 :"foo")都是同一个 Symbol 对象,其 object id 为327458,而后三行中的字符串”foo”都是不同的对象,其 object id 依次为24303850、24300010、24296170。

    可见,每个 String 对象都是不同的,即便他们包含了相同的字符串内容;而对于 Symbol 对象,一个名字(字符串内容)唯一确定一个 Symbol 对象Symbol 对象的字符串中不能含有’\0’字符)。

    除了可以采用一般的字符串,还可以使用操作符(例如+, -, *, /),变量,常量,方法甚至类的名字来创建 Symbol 对象,例如:+就是一个合法的 Symbol 。实际上,在 Ruby 内部操作符、变量等名字本身就是作为 Symbol 处理的,例如当你定义一个实例变量时, Ruby 会自动创建一个 Symbol 对象,例如 @test 对应为 :@test 。

    1实例变量的 Symbol
    2
    3class Test
    4 attr_accessor :test
    5end

    Symbol 和 String

    Symbol 对象和 String 对象是完全不同的东西,对象标识符很明确的说明了这一点。

    Symbol 转化为 String

    使用 to_s 或 id2name 方法将 Symbol 转化为一个 String 对象:

    irb(main):001:0> :test.id2name
    => "test"
    irb(main):002:0> :test.to_s
    => "test"
    irb(main):003:0> :"I am a boy".to_s
    => "I am a boy"
    

    注意,每个 String 对象都是唯一的,因此对一个 Symbol 调用多次将产生多个 String 对象。

    String 转化为 Symbol

    除了在字符串前面加冒号,还可以使用 to_sym 或 intern 方法将 String 转化为 Symbol ,如果该 Symbol 已经存在,则直接返回。

    1irb(main):001:0> var1 = "test".to_sym
    2=> :test
    3irb(main):002:0> var2 = "test".intern
    4=> :test
    5irb(main):003:0> var1 == var2
    6=> true
    7irb(main):004:0>

    使用 Symbol

    正如前边提到的, Ruby 内部一直在使用 Symbol ,比如 Ruby 程序中的各种名字,Symbol本质上是 Ruby 符号表中的东西。使用 Symbol 处理名字可以降低 Ruby 内存消耗,提高执行速度,这点我们在下一篇文章中会看到。

    那么 Symbol 对我们有什么用呢?当然也是内存。使用 String 的开销太大了,因为每一个String 都是一个对象。想想前边的例子,一个字符串每出现一次 Ruby 就会创建一个 String 对象。

    通常来讲,当你面临 String 还是 Symbol 的选择时,可以参考以下标准:

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

    那么什么时候我们会用到名字呢?很多时候都会,比如枚举值、关键字(哈希表关键字、方法的参数)等等

    作为哈希表的 key

    哈希表是 Symbol 应用最为广泛的地方。在ruby中,哈希和数组类似,一个哈希表是一系列 key/value 对的集合,只不过它的 key 取值范围更广泛,可以是任何对象,比如正则表达式。

    但通常我们都会取有意义的 key ,比如 String、Symbol 。

    下面这个哈希表表示按城市分类的一些机器的集合:

    1 hosts{
    2 'beijing' => 'machine1',
    3 'shanghai' => 'machine2',
    4 'guangzhou' => 'machine3',
    5 'tianjin' => 'machine4',
    6 'shenzhen' => 'machine5'
    7 }

    如果要引用 beijing 的机器,使用 hosts['beijing'] 。但如果我们程序中要频繁引用哈希表中 value ,这样就不大好了,因为 Ruby 对每一次字符串引用都会生成一个 String 对象,

    累积下来这个开销是相当大的,我们可以使用 Symbol 作为 key:

    hosts = {  :beijing => 'machine1',  :shanghai => 'machine2',  :guangzhou => 'machine3',  :tianjin  => 'machine4',  :shenzhen => 'machine5' }

    通常我们定义的函数的参数的个数和顺序是写死的,调用函数的时候要确保参数的个数、顺序匹配,有时候这样很不方便,使用哈希参数可以解决这个问题。

    使用哈希参数的方法调用①

    products = {:"0001"=>"手机",:"0002"=>"电脑"}

    puts products[:"0001"]
    使用哈希参数的方法调用②
    def my_method(p1,p2,options={})
      puts p1
      puts p2
      options.each{|key,value| puts "#{key} is #{value}"}
    end
    my_method("1","2",:title=>"标题",:id=>123)
    



  • 相关阅读:
    数据库的规范和SQL优化技巧总结
    新版Intellij idea破解方法(插件IDE Eval Reset)
    容易遗忘的知识点总结
    Java如何搭建脚手架(自动生成通用代码),创建自定义的archetype(项目模板)
    阿里云服务器域名解析和ICP域名备案
    云服务器通过ip无法访问
    FirewallD is not running 远程服务器开启端口报错
    [prerender-spa-plugin] Unable to prerender all routes! 内网打包报错(Navigation Timeout Exceeded)
    vue-cli中的 mode模式、env环境文件,以及其中定义的环境变量
    绘制柱状图和横向条形图,带数据标签!!!
  • 原文地址:https://www.cnblogs.com/leon19870907/p/2014904.html
Copyright © 2020-2023  润新知