`
zarknight
  • 浏览: 148223 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Ruby的符号(Symbol)

阅读更多
Ruby的符号足以让很多初学者迷惑上一段时间,看过本章节后,或许会解开你心中的疑惑。

在Ruby中,一个符号是就是一个Symbol类的实例,它的语法是在通常的变量名前加一个冒号,如
:my_sy

Ruby的符号像一个字符串,因为它内部表现形式是一个字符序列。而与字符串不同的是,每个符号的实例只有一个。看下面的例子:
array = ["foo", "foo", "foo", :foo, :foo, :foo]

建立这个数组后,内存中将有三个内容为"foo"的字符串对象,而只有一个:foo对象。

一个符号有它唯一对应的一个整数值,可以用to_i来获取它。

符号常用的地方是用它来代表变量名或者方法名:
class SomeClass
  attr_accessor :whatever
end

与上面程序对等的程序如下:
class SomeClass
  def whatever
    @whatever
  end
  def whatever=(val)
    @whatever = val
  end
end

你可能会问,为什么不用字符串来表示呢?其实,字符串也是可以的:
attr_reader :alpha
attr_reader "beta"   # 也是合法的

那它们的区别在哪里?某种意义上来说,是为了提高程序性能,节省内存吧。

有的人说,"符号就如同不可变的字符串",从它的行为上来说,可能是对的。但是,Symbol并是是继承至String,而且,与字符串相关
的那些典型操作方法,Symbol也不一定有,也不需要有。


符号不一定看起来是像变量一样,它也可以这样:
sym1 = :"This is a symbol"
sym2 = :"This is, too!"
sym3 = :")(*&^%$"
你可以用这样奇怪的符号来定义实例变量名或方法,你可以使用诸如send或instance_variable_get来获取它们的引用。虽然是可行的,
但请尽量不要使用这么奇怪的符号。


用Symbol作为枚举
==========================================
像Pascal或版本稍晚的C语言,都存在enum这种类型。Ruby不能正真的拥有这样的类型,因为它没有类型检查。但使用Symbol可以用来产生
这样的效果:
North, South, East, West = :north, :south, :east, :west

用Symbol作为元数据
==========================================
通常我们使用捕获异常的方式来处理错误,避免使用老式的返回代码的方式。但是,如果你想用老式的方式,还是可以的。像nil就是这样一个元数据。
我们通常可以这样使用(因为符号是全局的,所以在之后的整个程序中,都可以使用这些符号来作为元数据):
str = get_string
case str
  when String
    # Proceed normally
  when :eof
    # end of file, socket closed, whatever
  when :error
    # I/O or network error
  when :timeout
    # didn't get a reply
end


Symbols, Variables, Methods
==========================================
Symbol最常用的地方就是我们熟知的定义属性了:
class MyClass
  attr_reader :alpha, :beta
  attr_writer :gamma, :delta
  attr_accessor :epsilon
  # ...
end
这里的方法,如attr_accessor,它以传入的符号来确定实例变量的名称,以及读写属性的方法的名称,但这不代表所有的情况
(即总是会自动精确匹配符号和实例变量的名称),例如,当使用instance_variable_set方法的时候,符号和实例变量名必须
精确给出:
sym1 = :@foo
sym2 = :foo
instance_variable_set(sym1,"str")   # 正常,匹配到@foo
instance_variable_set(sym2,"str")   # 错误

不过,记住,在这些地方不一定要使用符号,可以用字符串来替代。


转换Symbol
============================================
Symbol和字符串之间可以互相转换,使用to_s和to_sym来实现:
a = "foobar"
b = :foobar
a == b.to_str    # true
b == a.to_sym    # true








 

分享到:
评论
1 楼 不想长大 2008-07-08  
:foobar是 一个变量。————冒号后面表示一个 变量

>> sym1 = :@foo
=> :@foo
>> sym2 = :foo
=> :foo
>> instance_variable_set(sym1,"str1")
=> "str1"
>> instance_variable_set(sym2,"str1")
NameError: `foo' is not allowed as an instance variable name


这里面的符号又是什么意思呢?

相关推荐

    符号的优雅:深入探索Ruby中的Symbol

    ### 符号的优雅:深入探索 Ruby 中的 Symbol #### 引言 在 Ruby 这门优雅且功能强大的编程语言中,符号(Symbol)占据着举足轻重的地位。符号不仅是 Ruby 性能优化的关键组成部分,也是理解 Ruby 核心特性的窗口之...

    symbol_decoration:支持 Ruby 符号修饰,例如 where(

    Symbol Decoration gem 提供了符号方法扩展来实现 DSL,例如where(:field.in => [1,2,3]) 。 目标是允许不同的 ORM(例如 Mongoid 和 NoBrainer)共存,因为这两个 ORM 都需要此类功能。 用法 在以下示例中: where...

    ruby官方chm文档

    例如,它会详细介绍如何创建和使用类、继承机制、模块混入、块和 Proc 对象,以及符号(Symbol)、字符串(String)、数组(Array)、哈希(Hash)等基本数据类型的使用。核心库的理解对于掌握Ruby语言至关重要。 ...

    Ruby元编程第二版中文

    符号(Symbol)在Ruby中是特殊的,它们在内存中只存在一份,常用于元编程中的键值。 5. **Proc对象与lambda**:Ruby的`Proc`和`lambda`可以创建匿名函数,它们可以被赋值给变量,作为参数传递,或者用作方法的...

    eloquent ruby

    - 符号(Symbol)的高效利用。 - Lambda与Proc的区别。 5. **Ruby元编程** - 元编程是Ruby的核心优势之一。 - 动态创建方法和属性。 - 使用评估(Evaluation)和反射(Reflection)技术。 - 扩展和覆盖内置行为。 ...

    ruby trap 初学者使用

    2. **符号(Symbol)**: - 符号是Ruby中的一种特殊数据类型,它们是不可变的,常用于哈希键和方法调用。理解符号与字符串的区别对于优化内存使用至关重要。 3. **块和 Proc/Lambda**: - Ruby中的块(由`do......

    learning-ruby.

    1. **变量和数据类型**:Ruby支持多种数据类型,包括整型(Integer)、浮点型(Float)、字符串(String)、布尔型(Boolean)以及符号(Symbol)。此外,Ruby还有数组(Array)和哈希(Hash)等复合数据类型。 2. ...

    ruby程序安装文件

    5. **符号(Symbol)**:Ruby引入了一种特殊的不可变对象——符号,用于表示唯一的标识符,节省内存。 6. **GVL(全局解释器锁)**:在Ruby 2.1.0版本中,虽然已经对GVL进行了优化,但仍然存在,这限制了并发执行的...

    ruby metaprograming

    符号(Symbol) 符号是Ruby中的一种数据类型,它是一个不可变的字符串。在元编程中,符号经常被用作标识符来指代方法或属性,从而避免不必要的字符串创建。 **示例**: ```ruby def self.method_missing(name, *args...

    ruby2.6.1.zip

    5. **Symbol到Proc转换的改进**:在Ruby 2.6.1中,使用`&:`操作符将符号转换为Proc更加高效,这在构建函数式编程模式时尤其有用。 6. **Ruby编译器选项**:这个版本增加了新的编译器选项,如`--enable-jit`(Just-...

    ruby入门练习题.zip

    7. **符号(Symbol)**:Ruby中的符号是不可变的,它们在内存中只存储一份,适用于作为哈希表的键,提高查找效率。 8. **块和 Proc**:Ruby中的块是代码的另一个形式,可以用`do..end`或者花括号`{}`包裹。Proc对象...

    Python & Ruby 学习

    7. **符号(Symbol)**:Ruby 中的符号是不可变的对象,常用于哈希表键,以节省内存。 8. **动态类型**:与Python一样,Ruby 也支持动态类型,变量类型由赋值决定。 至于“源码”和“工具”标签,这可能意味着...

    ruby-2.0.0-p0.tar

    7. **Symbol垃圾收集**:在Ruby 2.0之前,所有创建的Symbol都会永久存在内存中,但在2.0中,未使用的Symbol会被垃圾收集器回收,节省了内存。 8. **YARV虚拟机优化**:Ruby 2.0继续使用YARV(Yet Another Ruby VM)...

    ruby-2.3.0

    另一个值得注意的改进是增加了`Symbol#to_proc`的性能。这个特性让符号能够转换为 Proc 对象,从而简化了块的传递。这对于函数式编程风格的Ruby代码来说是个巨大的提升,尤其是在使用`Array#map`、`Array#select`等...

    二十分钟Ruby入门教程

    Ruby有几种基本的数据类型,包括整数(如`5`)、浮点数(如`3.14`)、字符串(用引号括起来,如`"Hello"`,支持单引号和双引号两种)、布尔值(`true`或`false`)以及符号(以冒号开头,如`:symbol`)。另外,数组和...

    ruby-2.3.3tar.gz

    5. **Symbol#to_proc (符号到Proc的转换)**:现在,符号可以被转换为一个Proc,进一步增强了函数式编程的能力。 6. **Improved Encoding Support (增强的编码支持)**:Ruby-2.3.3改进了对多种编码格式的支持,使得...

    Programming Ruby 1.9 (3rd edition)和源码

    - 符号(Symbol):不可变的哈希键,用于节省内存。 - 范围(Range):表示一个数值范围,支持遍历操作。 4. **控制结构**: - 条件语句:`if`、`unless`、`case`等用于条件判断。 - 循环:`for`、`while`、`...

Global site tag (gtag.js) - Google Analytics