74

Ruby 中的字符串和符号之间有什么区别,我什么时候应该使用一个而不是另一个?

4

11 回答 11

93

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

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。

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

于 2008-10-31T22:11:01.363 回答
17

符号和字符串有什么区别?

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

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

如果你懂中文,你也可以阅读理解 Ruby Symbol

于 2014-04-29T07:46:31.757 回答
7

该声明:

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

此外,符号是不可变的,您不能调用任何字符串方法,如符号upcasesplit符号。

比较符号比比较字符串更快。符号可以被认为是形成一个唯一集合的常量/不可变字符串,这些字符串有效地转换为堆上的内存指针。这意味着比较两个符号很快,因为您只是比较两个整数(内存指针)。

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

当您确定值将保持不变时使用符号,例如使用符号作为哈希键。当您想要更改值或想要对其使用字符串方法时,请使用字符串。

于 2016-09-15T19:23:55.810 回答
5

String和之间的另一个区别Symbol是 aString有更多用于字符串操作的方法,而 aSymbol是一个相对精简的对象。

查看StringclassSymbolclass的文档。

于 2008-11-01T18:24:46.483 回答
2

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

  1. String 是可变的,而 Symbol 不是:

    • 因为字符串是可变的,它可以在某个地方发生变化,并可能导致结果不正确。
    • 符号是不可变的。
  2. String 是一个 Object 所以它需要内存分配

    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
    

因此,String 的使用和比较时间将比 Symbol 多。

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

于 2016-07-05T00:00:13.250 回答
2

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

于 2019-01-15T17:23:59.137 回答
0

主要区别在于 string 可以在变量内具有值,而 symbol 不能。例如:

x     =     "hello"
p x  =>     "hello"
p :x =>     :x
于 2021-08-18T05:46:59.953 回答
-1

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

刚刚通过谷歌找到了这个,它可能会提供更多的细节:给你

于 2008-10-31T22:02:52.427 回答
-1

符号和字符串完全不同,这篇文章对差异有一点了解。至于何时何地使用它们,关于这个主题有一篇相当广泛的帖子,上面有很多 :through

于 2008-10-31T22:04:43.093 回答
-1

字符串是可变的,符号是不可变的
注意:可变对象可以在赋值后更改,而不可变对象只能被覆盖 http://www.robertsosinski.com/2009/01/11/the-difference-between-ruby-symbols-and -字符串/

于 2013-07-21T18:24:58.063 回答
-1

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

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

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

欲了解更多信息,您可以点击这里

于 2014-03-17T12:14:56.927 回答