从 Ruby 2.3 开始不可变String
已可选地通过以下方式实现RUBYOPT
flag --enable-frozen-string-literals
i.e.
RUBYOPT=--enable-frozen-string-literals ruby /some/file
这将导致所有String
文字(使用创建的字符串""
, %q{}
, %Q{}
,或“#{}”样式)变得不可变。该功能目前被认为是 Ruby 3.0 的默认功能。按照功能#11473 进行操作 https://bugs.ruby-lang.org/issues/11473。此功能还可以在文件级别而不是全局级别上作为“神奇注释”使用
# frozen_string_literal: true
这将产生与RUBYOPT
版本但仅适用于特定文件。 (另一种方法是直接与虚拟机交互RubyVM::InstructionSequence.compile_option = {frozen_string_literal: true}
)
由于这是可选的,显然它可以打开和关闭,并且仍然是 3.0 中的一个选项,只是默认为打开而不是关闭。可变的String
s 仍然可以使用创建String.new
和不可变的String
可以是dup
ed 使他们的dup
对应部分可变。 (请注意上面:插值"#{}"
还创建了一个新的不可变字符串,因为""
)
话虽如此,它并不能取代Symbols
在红宝石中。首先是底层C
为红宝石杠杆提供动力Symbols
大量通过rb_itern
处理方法定义等内容的引用(这些内容的标题为《不朽的符号》并且永远不会被GCed)。
此外Symbols
就像 ruby 中的所有东西都是它们自己的一样Object
并拥有自己有用的功能集。拿Symbol#to_proc
例如。这最初是一个猴子补丁解决方案,旨在简化语法,并在 1.8.7 中被消耗到核心中。这种风格受到整个 Ruby 社区的高度鼓励和定期利用。请告知您如何建议将此功能降级与String
代替Symbol
.
While Symbols
由于它们的驻留和内存消耗与红宝石的动态相结合,曾经被认为有些“危险”(因为没有更好的词)。从 Ruby 2.2 开始,大多数Symbols
(见上文)可以被垃圾收集,即通过以下方式在 ruby 内部创建的符号String
拘留(#intern
, #to_sym
, ETC。)。 (这些都是被创造出来的《凡人的象征》)
小警告包括诸如
define_method(param[:meth].to_sym) {}
这似乎是因为它正在调用to_sym
它应该是一个《凡人的象征》但是由于define_method
calls rb_intern
为了保留方法引用,它实际上会创建一个《不朽的象征》
希望这个总结有助于解释必要性Symbol
在 ruby 中,不仅从开发人员的角度来看,而且作为C
ruby 实现的内部结构。