在Java中,字符串是不可变的和实体的.所以“foo”在值和引用中总是等于“foo”,它的值不能改变.在Ruby中,字符串是可变的而不是实体,因此“a”.object_id ==“a”.object_id将为false.
如果Ruby实现了像Java这样的字符串,那么符号就没有必要了,对吧?
从Ruby 2.3开始,不可变的字符串可选地通过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.new创建可变字符串,并且可以使用不可变字符串来使其dup计数器部分可变. (请注意以上内容:插值“#{}”也会创建一个新的不可变字符串,因为“”)
所有这一切都没有取代ruby中符号的需要.首先,支持ruby的底层C通过rb_itern大量利用符号来处理方法定义之类的引用(这些引用标题为“不朽符号”,永远不会被GCed).
另外像ruby中的所有东西的符号都是它们自己的Object,并且有自己有用的功能集.以Symbol#to_proc为例.这起源于猴子补丁解决方案的语法简易性,并在1.8.7中被用于核心.这种风格受到ruby社区的高度鼓励和定期利用.请告知您如何建议使用String而不是Symbol来降低此功能.
虽然Symbols过去被认为有点“危险”(缺乏一个更好的词),因为它们的内容和记忆消耗与ruby的动态相结合.从Ruby 2.2开始,大多数符号(见上文)可以被垃圾收集,即通过String internment(#intern,#to_sym等)在ruby内部创建的符号. (这些已被创造出“凡人符号”)
小问题包括类似的事情
define_method(param[:meth].to_sym) {}
这似乎是因为它调用to_sym它应该是一个“凡人符号”但是因为define_method调用rb_intern来保持方法引用它实际上会创建一个“不朽符号”
希望这种向下运行有助于解释Symbol在ruby中的必要性,不仅从开发人员的角度来看,还有大量使用作为Ruby实现的C内部的一部分.