Ruby中的字符串和符号有什么区别?


Answers:


87

主要区别在于代表单个值的多个符号是相同的,而对于字符串则不是这样。例如:

irb(main):007:0> :test.object_id
=> 83618
irb(main):008:0> :test.object_id
=> 83618
irb(main):009:0> :test.object_id
=> 83618

这是对symbol的三个引用:test,它们都是同一对象。

irb(main):010:0> "test".object_id
=> -605770378
irb(main):011:0> "test".object_id
=> -605779298
irb(main):012:0> "test".object_id
=> -605784948

这些是对字符串“ test”的三个引用,但是都是不同的对象。

这意味着根据应用程序的不同,使用符号可能会节省大量内存。比较符号是否相等也更快,因为它们是同一对象,比较相同的字符串要慢得多,因为需要比较字符串值而不是对象ID。

至于何时使用它,我通常在几乎所有东西上都使用字符串,除了像哈希键之类的东西外,我真的想要一个唯一的标识符,而不是字符串。


9
尽管符号不会被垃圾收集器清除,并一直存在直到运行时实例结束。因此,如果声明很多符号,可能会浪费大量内存。

6
@Daemin:除非您正在动态创建符号,否则这通常不是问题。这是某些应用程序内存膨胀的原因。如果在代码中使用硬编码符号,则相对安全。
Pistos

2
我不确定我是否理解你的第一句话。人们说每个雪花都是独一无二的,这意味着每个雪花都是不同的。每种情况都不同。但是,在您的符号代码示例中,您显示每次出现都是完全相同的对象。“相同”不是更好的词吗?
马丁·海姆斯

16

Symbols和Strings有什么区别?

  1. 符号是不可变的:它们的值保持不变。
  2. 与字符串相比,相同符号的多次使用具有相同的对象ID,并且是同一对象,而字符串则每次都是具有唯一对象ID的不同对象。
  3. 您不能像split在Symbols上那样调用任何String方法。

了解Ruby中符号和字符串之间的差异

如果您会中文,也可以阅读理解Ruby Symbol


6

该声明:

foo = "bar"

在内存中创建一个新对象。如果我们重复该语句:

foo = "bar"

我们创建另一个对象。

为了更清楚地理解它,请在IRB中尝试以下代码:

foo = "bar"
puts "string #{foo} with object id = #{foo.object_id}"
foo = "bar"
puts "string #{foo} with object id = #{foo.object_id}"

您将得到如下输出:

string bar with object id = 70358547221180
string bar with object id = 70358548927060

它清楚地表明同一字符串有两个不同的对象。现在,如果您使用一个符号,它将为每个符号创建一个对象,因此:

foo = :bar
puts "symbol #{foo} with object id = #{foo.object_id}"
foo = :bar
puts "symbol #{foo} with object id = #{foo.object_id}"

显示:

symbol bar with object id = 7523228
symbol bar with object id = 7523228

表示仅有一个对象:bar

此外,Symbol是不可变的,您不能调用任何String方法,例如upcasesplitSymbol或。

比较符号比比较字符串要快。可以将符号视为恒定/不可变的字符串,它们形成一个唯一的集合,并被有效地转换为堆上的内存指针。这意味着比较两个符号的速度很快,因为您只是比较两个整数(内存指针)。

字符串是可变的,因此修改后指向堆上其值的内存指针可以更改。这意味着比较操作较慢,因为可以存在语义上等效的重复项。

当您确定该值将保持恒定时,请使用符号,例如,将符号用于哈希键。当您要更改值或要在其上使用字符串方法时,请使用字符串。



2

Ruby中的String和Symbol之间有两个主要区别。

  1. 字符串是可变的,而符号不是:

    • 由于String是可变的,因此可以在某个地方进行更改,并可能导致结果不正确。
    • 符号是不可变的。
  2. 字符串是一个对象,因此需要分配内存

    puts "abc".object_id # 70322858612020
    puts "abc".object_id # 70322846847380
    puts "abc".object_id # 70322846815460
    

    另一方面,Symbol将返回相同的对象:

    puts :abc.object_id # 1147868
    puts :abc.object_id # 1147868
    puts :abc.object_id # 1147868
    

因此,与Symbol相比,String需要更多的时间来使用和比较。

阅读“ Ruby符号和字符串之间的区别”以获取更多信息。


1

符号可能是灾难的情况。可以说您 params.map(&:to_sym)在rails控制器中。现在在这里,如果由于某种原因将用户提供的数据转换为符号,则可能很危险。如果用户提供的数据太大,并且我们知道该符号不是垃圾收集器,您可能最终会耗尽服务器的内存,这可能会导致您的网站瘫痪。


0

符号是用来表示名称和字符串的东西。当您可能需要多次使用一个字符串时,您可能会想使用一个符号,因为这样做更容易且效率更高。

刚刚通过google找到了它,它可能会提供更多详细信息:在这里


提供链接时,请总结页面上的重要信息并提供署名。链接腐烂然后断开,导致信息无用。“如何参考他人撰写的材料”将有助于解释。
锡人



-1

符号是不可变的,字符串是可变的。

当我们对字符串执行任何操作时,它将创建一个新对象并占用内存。随着对字符串执行越来越多的操作,意味着我们正在消耗越来越多的内存。

符号是不可变的对象,如果我们执行任何操作,它将对原始对象进行更改,它将不创建任何对象,这就是为什么它更有利可图的原因。

有关更多信息,您可以单击此处


链接断开。请阅读“如何参考他人撰写的材料”。
锡人
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.