简体   繁体   English

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

[英]Is StringBuffer the same as Strings in Ruby and Symbols the same as regular Java strings?

I just started reading this book Eloquent Ruby and I have reached the chapter about Symbols in Ruby.我刚开始阅读这本书Eloquent Ruby并且我已经阅读了 Ruby 中关于符号的章节。

Strings in Ruby are mutable, which means each string allocate memory since the content can change, and even though the content is equal. Ruby 中的字符串是可变的,这意味着每个字符串分配 memory 因为内容可以更改,即使内容相同。 If I need a mutable String in Java I would use StringBuffer.如果我需要 Java 中的可变字符串,我会使用 StringBuffer。 However since regular Java Strings are immutable one String object can be shared by multiple references.但是,由于常规 Java 字符串是不可变的,因此一个字符串 object 可以由多个引用共享。 So if I had two regular Strings with the content of "Hello World", both references would point to the same object.因此,如果我有两个内容为“Hello World”的常规字符串,则两个引用都指向同一个 object。

So is the purpose of Symbols in Ruby actually the same as "normal" String objects in Java?那么 Ruby 中 Symbols 的用途实际上与 Java 中的“普通”字符串对象相同吗? Is it a feature given to the programmer to optimize memory?是给程序员优化memory的功能吗?

Is something of what I written here true?我在这里写的东西是真的吗? Or have I misunderstood the concept of Symbols?还是我误解了符号的概念?

Symbols are close to strings in Ruby, but they are not the equivalent to regular Java strings, although they, too, do share some commonalities such as immutability.符号与 Ruby 中的字符串很接近,但它们并不等同于常规的 Java 字符串,尽管它们也确实具有一些共同点,例如不变性。 But there is a slight difference - there is more than one way to obtain a reference to a Symbol (more on that later on).但是有一点点不同 - 获得对符号的引用的方法不止一种(稍后会详细介绍)。

In Ruby, it is entirely possible to convert the two back and forth.在Ruby中,两者来回转换是完全可以的。 There is String#to_sym to convert a String into a Symbol and there is Symbol#to_s to convert a Symbol into a String.有 String#to_sym 可以将 String 转换为 Symbol,还有 Symbol#to_s 可以将 Symbol 转换为 String。 So what is the difference?那么区别是什么呢?

To quote the RDoc for 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.在程序执行期间,将为给定名称或字符串创建相同的符号 object,无论该名称的上下文或含义如何。

Symbols are unique identifiers.符号是唯一标识符。 If the Ruby interpreter stumbles over let's say :mysymbol for the first time, here is what happens: Internally, the symbol gets stored in a table if it doesn't exist yet (much like the "symbol table" used by parsers; this happens using the C function rb_intern in CRuby/MRI), otherwise Ruby will look up the existing value in the table and use that.如果 Ruby 解释器绊倒了让我们说:mysymbol第一次,会发生以下情况:在内部,如果符号不存在,则将其存储在表中(很像解析器使用的“符号表”;这种情况会发生在 CRuby/MRI 中使用 C function rb_intern ),否则 Ruby 将在表中查找现有值并使用它。 After the symbol gets created and stored in the table, from then on wherever you refer to the Symbol :mysymbol , you will get the same object, the one that was stored in that table.在创建符号并将其存储在表中之后,从那时起,无论您在何处引用 Symbol :mysymbol ,您都将获得相同的 object,即存储在该表中的那个。

Consider this piece of code:考虑这段代码:

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

to notice the difference.注意到差异。 It illustrates the major difference between Java Strings and Ruby Symbols.它说明了 Java 字符串和 Ruby 符号之间的主要区别。 If you want object equality for Strings in Java you will only achieve it if you compare exactly the same reference of that String, whereas in Ruby it's possible to get the reference to a Symbol in multiple ways as you saw in the example above.如果您希望 Java 中的字符串的 object 相等,则只有比较该字符串的完全相同的引用才能实现它,而在 Ruby 中,可以通过上述示例以多种方式获得对符号的引用。

The uniqueness of Symbols makes them perfect keys in hashes: the lookup performance is improved compared to regular Strings since you don't have to hash your key explicitly as it would be required by a String, you can simply use the Symbol's unique identifier for the lookup directly. Symbols 的唯一性使它们成为哈希中的完美键:与常规字符串相比,查找性能有所提高,因为您不必像字符串所需要的那样显式 hash 您的键,您可以简单地使用符号的唯一标识符直接查找。 By writing :somesymbol you tell Ruby to "give me that one thing that you stored under the identifier 'somesymbol'".通过写:somesymbol你告诉 Ruby “给我你存储在标识符 'somesymbol' 下的一个东西”。 So symbols are your first choice when you need to uniquely identify things as in:因此,当您需要唯一标识以下内容时,符号是您的首选:

  • hash keys hash 钥匙
  • naming or referring to variable, method and constant names (eg obj.send:method_name )命名或引用变量、方法和常量名称(例如 obj.send:method_name )

But, as Jim Weirich points out in the article below, Symbols are not Strings, not even in the duck-typing sense.但是,正如 Jim Weirich 在下面的文章中指出的那样,符号不是字符串,甚至在鸭子打字的意义上也不是。 You can't concatenate them or retrieve their size or get substrings from them (unless you convert them to Strings first, that is).您不能连接它们或检索它们的大小或从中获取子字符串(除非您先将它们转换为字符串)。 So the question when to use Strings is easy - as Jim puts it:所以何时使用字符串的问题很简单——正如 Jim 所说:

Use Strings whenever you need … umm … string-like behavior.在需要时使用字符串……嗯……类似字符串的行为。

Some articles on the topic:关于该主题的一些文章:

The difference is that Java Strings need not point to the same object if they contain the same text.不同之处在于,如果 Java 字符串包含相同的文本,则它们不需要指向相同的 object。 When declaring constant strings in your code, this normally is the case since the compiler will put it in the constant pool.在代码中声明常量字符串时,通常是这种情况,因为编译器会将其放入常量池中。

However, if you create a String dynamically at runtime in Java, two Strings can perfectly point to different objects and still contain the same literal text.但是,如果您在运行时动态创建一个 String 在 Java 中,两个 String 可以完美地指向不同的对象,并且仍然包含相同的文字文本。 You can however force this by internalizing the String objects (calling String.intern(), see Java API但是,您可以通过内部化 String 对象来强制执行此操作(调用 String.intern(),请参阅Java API

A nice example can be found here .一个很好的例子可以在这里找到。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM