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
分享到:
相关推荐
### 符号的优雅:深入探索 Ruby 中的 Symbol #### 引言 在 Ruby 这门优雅且功能强大的编程语言中,符号(Symbol)占据着举足轻重的地位。符号不仅是 Ruby 性能优化的关键组成部分,也是理解 Ruby 核心特性的窗口之...
Symbol Decoration gem 提供了符号方法扩展来实现 DSL,例如where(:field.in => [1,2,3]) 。 目标是允许不同的 ORM(例如 Mongoid 和 NoBrainer)共存,因为这两个 ORM 都需要此类功能。 用法 在以下示例中: where...
例如,它会详细介绍如何创建和使用类、继承机制、模块混入、块和 Proc 对象,以及符号(Symbol)、字符串(String)、数组(Array)、哈希(Hash)等基本数据类型的使用。核心库的理解对于掌握Ruby语言至关重要。 ...
符号(Symbol)在Ruby中是特殊的,它们在内存中只存在一份,常用于元编程中的键值。 5. **Proc对象与lambda**:Ruby的`Proc`和`lambda`可以创建匿名函数,它们可以被赋值给变量,作为参数传递,或者用作方法的...
- 符号(Symbol)的高效利用。 - Lambda与Proc的区别。 5. **Ruby元编程** - 元编程是Ruby的核心优势之一。 - 动态创建方法和属性。 - 使用评估(Evaluation)和反射(Reflection)技术。 - 扩展和覆盖内置行为。 ...
2. **符号(Symbol)**: - 符号是Ruby中的一种特殊数据类型,它们是不可变的,常用于哈希键和方法调用。理解符号与字符串的区别对于优化内存使用至关重要。 3. **块和 Proc/Lambda**: - Ruby中的块(由`do......
1. **变量和数据类型**:Ruby支持多种数据类型,包括整型(Integer)、浮点型(Float)、字符串(String)、布尔型(Boolean)以及符号(Symbol)。此外,Ruby还有数组(Array)和哈希(Hash)等复合数据类型。 2. ...
5. **符号(Symbol)**:Ruby引入了一种特殊的不可变对象——符号,用于表示唯一的标识符,节省内存。 6. **GVL(全局解释器锁)**:在Ruby 2.1.0版本中,虽然已经对GVL进行了优化,但仍然存在,这限制了并发执行的...
符号(Symbol) 符号是Ruby中的一种数据类型,它是一个不可变的字符串。在元编程中,符号经常被用作标识符来指代方法或属性,从而避免不必要的字符串创建。 **示例**: ```ruby def self.method_missing(name, *args...
5. **Symbol到Proc转换的改进**:在Ruby 2.6.1中,使用`&:`操作符将符号转换为Proc更加高效,这在构建函数式编程模式时尤其有用。 6. **Ruby编译器选项**:这个版本增加了新的编译器选项,如`--enable-jit`(Just-...
7. **符号(Symbol)**:Ruby中的符号是不可变的,它们在内存中只存储一份,适用于作为哈希表的键,提高查找效率。 8. **块和 Proc**:Ruby中的块是代码的另一个形式,可以用`do..end`或者花括号`{}`包裹。Proc对象...
7. **符号(Symbol)**:Ruby 中的符号是不可变的对象,常用于哈希表键,以节省内存。 8. **动态类型**:与Python一样,Ruby 也支持动态类型,变量类型由赋值决定。 至于“源码”和“工具”标签,这可能意味着...
7. **Symbol垃圾收集**:在Ruby 2.0之前,所有创建的Symbol都会永久存在内存中,但在2.0中,未使用的Symbol会被垃圾收集器回收,节省了内存。 8. **YARV虚拟机优化**:Ruby 2.0继续使用YARV(Yet Another Ruby VM)...
另一个值得注意的改进是增加了`Symbol#to_proc`的性能。这个特性让符号能够转换为 Proc 对象,从而简化了块的传递。这对于函数式编程风格的Ruby代码来说是个巨大的提升,尤其是在使用`Array#map`、`Array#select`等...
Ruby有几种基本的数据类型,包括整数(如`5`)、浮点数(如`3.14`)、字符串(用引号括起来,如`"Hello"`,支持单引号和双引号两种)、布尔值(`true`或`false`)以及符号(以冒号开头,如`:symbol`)。另外,数组和...
5. **Symbol#to_proc (符号到Proc的转换)**:现在,符号可以被转换为一个Proc,进一步增强了函数式编程的能力。 6. **Improved Encoding Support (增强的编码支持)**:Ruby-2.3.3改进了对多种编码格式的支持,使得...
- 符号(Symbol):不可变的哈希键,用于节省内存。 - 范围(Range):表示一个数值范围,支持遍历操作。 4. **控制结构**: - 条件语句:`if`、`unless`、`case`等用于条件判断。 - 循环:`for`、`while`、`...