java - StringBuffer 是否与 Ruby 中的字符串相同,Symbols 是否与常规 Java 字符串相同?

标签 java ruby string symbols

我刚开始读这本书Eloquent Ruby我已经读到关于 Ruby 中的符号的章节。

Ruby 中的字符串是可变的,这意味着每个字符串都会分配内存,因为内容可以更改,即使内容相同。如果我需要 Java 中的可变字符串,我会使用 StringBuffer。然而,由于常规的 Java 字符串是不可变的,一个字符串对象可以被多个引用共享。因此,如果我有两个内容为“Hello World”的常规字符串,两个引用将指向同一个对象。

那么 Ruby 中 Symbols 的用途实际上与 Java 中的“普通”String 对象相同吗?优化内存是给程序员的一个特性吗?

我在这里写的东西是真的吗?还是我误解了符号的概念?

最佳答案

符号与 Ruby 中的字符串很接近,但它们并不等同于常规的 Java 字符串,尽管它们也有一些共同点,例如不变性。但是有一个细微的差别——有不止一种方法可以获取对 Symbol 的引用(稍后会详细介绍)。

在Ruby中,完全可以将两者来回转换。有 String#to_sym 将字符串转换为符号,有 Symbol#to_s 将符号转换为字符串。那么区别是什么呢?

为 Symbol 引用 RDoc:

The same Symbol object will be created for a given name or string for the duration of a program‘s execution, regardless of the context or meaning of that name.

符号是唯一的标识符。如果 Ruby 解释器第一次遇到 :mysymbol 错误,会发生以下情况:在内部,如果符号不存在,它会存储在一个表中(很像“符号表” "由解析器使用;这发生在 CRuby/MRI 中使用 C 函数 rb_intern),否则 Ruby 将查找表中的现有值并使用它。在符号创建并存储在表中之后,从那时起,无论您在何处引用符号 :mysymbol,您都将获得相同的对象,即存储在该表中的对象。

考虑这段代码:

sym1 = :mysymbol
sym2 = "mysymbol".to_sym

puts sym1.equal?(sym2) # => true, one and the same object

str1 = "Test"
str2 = "Test"

puts str1.equal?(str2) # => false, not the same object

注意区别。它说明了 Java 字符串和 Ruby 符号之间的主要区别。如果您希望 Java 中的字符串对象相等,则只有比较该字符串的完全相同的引用才能实现它,而在 Ruby 中,可以通过多种方式获取对 Symbol 的引用,如您在上面的示例中看到的那样。

Symbols 的唯一性使它们成为散列中的完美键:与常规字符串相比,查找性能有所提高,因为您不必像字符串所要求的那样显式地散列您的键,您可以简单地使用 Symbol 的唯一性直接查找的标识符。通过编写 :somesymbol,你告诉 Ruby “给我你存储在标识符‘somesymbol’下的东西”。因此,当您需要唯一标识事物时,符号是您的首选,例如:

  • 散列键
  • 命名或引用变量、方法和常量名称(例如 obj.send :method_name )

但是,正如 Jim Weirich 在下面的文章中指出的那样,Symbols 不是 Strings,即使在 duck-typing 意义上也不是。您不能连接它们或检索它们的大小或从中获取子字符串(除非您先将它们转换为字符串)。所以何时使用字符串的问题很简单——正如 Jim 所说:

Use Strings whenever you need … umm … string-like behavior.

关于该主题的一些文章:

关于java - StringBuffer 是否与 Ruby 中的字符串相同,Symbols 是否与常规 Java 字符串相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6733423/

相关文章:

iOS swift : Formatting a custom Currency Number

python - 从 DataFrame 列中提取特定字符/文本

java - 404 请求的资源在非常简单的 servlet 上不可用

java - 复杂模式匹配

java - 何时在 Angular + Java 项目中使用 DTO 和 Matpstruct

ruby - 传递一个 block 并内联执行?

java - 我们可以从网站提交的表格中获取哪些可能的数据

ruby - 迭代 n 到 Ruby 可枚举中的最后一项

ruby-on-rails - 生成 Rails 迁移,如何将迁移文件名自动放入剪贴板?

比较C中的两个字符串?