我已经使用 Ruby 大约一年了,有一个语言问题:符号是必需的吗,因为 Ruby 字符串是可变的而不是固定的?
例如,在 Java 中,字符串是不可变的并且是固定的。所以“foo”在值(value)和引用上总是等于“foo”,并且它的值(value)不能改变。在 Ruby 中,字符串是可变的而不是固定的,因此 "a".object_id == "a".object_id
将为 false。
如果 Ruby 像 Java 一样实现了字符串,就不需要符号了,对吧?
最佳答案
从 Ruby 2.3 开始,不可变的 String
可以通过 RUBYOPT
标记 --enable-frozen-string-literals
实现
即
RUBYOPT=--enable-frozen-string-literals ruby /some/file
这将导致所有 String
文字(使用 ""
、%q{}
、%Q{} 创建的字符串
或“#{}”样式)变得不可变。此功能当前被视为 Ruby 3.0 的默认功能。 Follow along with Feature#11473 .此功能也可在文件级别而不是全局级别作为“魔术评论”使用
# frozen_string_literal: true
这将与 RUBYOPT
版本产生相同的影响,但仅适用于特定文件。 (另一种方法是直接与 VM 交互 RubyVM::InstructionSequence.compile_option = {frozen_string_literal: true}
)
因为这是可选的,显然它可以打开和关闭,并且在 3.0 中仍然是一个选项,只是默认为打开而不是关闭。可变的 String
仍然可以使用 String.new
创建,不可变的 String
可以被 dup
来创建它们dup
计数器部分可变。 (请注意上面:由于 ""
,插值 "#{}"
也会创建一个新的不可变字符串)
尽管如此,它并不能取代 ruby 中对 Symbols
的需求。首先,为 ruby 提供支持的底层 C
通过 rb_itern
大量利用 Symbols
来处理方法定义之类的引用(这些被命名为 "Immortal Symbols" 并且永远不会被 GC)。
此外,Symbols
就像 ruby 中的所有东西一样,都是它们自己的 Object
并且有它们自己有用的功能集。以 Symbol#to_proc
为例。这起源于语法简化的猴子补丁解决方案,并在 1.8.7 中被纳入核心。这种风格受到整个 ruby 社区的高度鼓励和经常利用。请告知您如何建议使用 String
而不是 Symbol
来降低此功能。
虽然 Symbols
过去常常被认为有些“危险”(因为缺少更好的词),因为它们的拘禁和内存消耗与 ruby 的动态相结合。从 Ruby 2.2 开始,大多数 Symbols
(见上文)都可以被垃圾收集,即通过 String
internment 在 ruby 内部创建的符号(#intern
,#to_sym
等)。 (这些被创造为“凡人的象征”)
次要注意事项包括
define_method(param[:meth].to_sym) {}
这似乎是因为它正在调用 to_sym
它应该是一个 “凡人符号” 但是因为 define_method
调用 rb_intern
为了保留方法引用,它实际上会创建一个“不朽符号”
希望这篇文章有助于解释 Symbol
在 ruby 中的必要性,不仅从开发人员的角度,而且作为 ruby 实现的 C
内部的一部分的大量使用。
关于ruby - Ruby 符号是否存在是因为字符串是可变的而不是 interned 的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44634073/