为什么使用 :"string val" 符号来声明一个符号

Why use the :"string val" notation to declare a symbol

:"String Val" 创建一个存储 "String Val" 的符号。 :"Hello Kitty".class returns Symbol。我想这是为了创建一个有空格的符号。除了强制需要符号的方法之外,我想不出任何有用的原因。

还有其他使用它的理由吗?

这是另一个用例:

:3
# => syntax error, unexpected tINTEGER, expecting tSTRING_CONTENT or tSTRING_DBEG or tSTRING_DVAR or tSTRING_END

:"3"
# => :"3"

这不仅仅是空格,它是任何乱码,否则将被视为应该解释的东西。喜欢

:"zoo@-55**12 +foo(3, baz)[7] - ❤️"

引号表示 "use as is"。这使得它们作为字符串的文字语法很直观,但您可以看到还有其他用途。


但是说 "just" 方法需要符号而不是字符串有点误导。尽管 Rails 试图让您相信,符号和字符串是非常不同的,应该区别对待。符号通常用作一种神奇的常量,而字符串是常规值。

这就像在说我们为什么需要String#to_i。是否仅适用于以不同方式对待 42"42" 的方法?


至于为什么有它的字面语法 - 只是为了方便(就像任何其他语法糖一样)。考虑:

{
  something_something:            1,
  something_completely_different: 2,
  'yet something else':           3,
}

如果我们不得不这样写就很不幸了:

{
  :something_something            => 1,
  :something_completely_different => 2,
  'yet something else'.to_sym     => 3,
}

{
  something_something:            1,
  something_completely_different: 2,
  'yet something else'.to_sym =>  3,
}

重要的原因是利用字符串插值,它允许动态生成符号。

5.times.map{ |x| :"symbol_#{x}" }
=> [:symbol_0, :symbol_1, :symbol_2, :symbol_3, :symbol_4]

已经有 String#to_sym。鉴于这一事实,:"..." 似乎是一种语法糖,可以随时用 String#to_sym 代替。但事实并非如此。除了为了程序员的方便,不管String#to_sym是否存在,都必须有一个符号:"...",至少为了检查。在这个例子中,

"foo bar".to_sym
# => :"foo bar"

检查形式不能是"foo bar".to_sym,表示将一个方法应用到一个字符串上,因为同一个对象可以有很多其他方式得到,而这只是创建这种对象的一种方式。这种符号必须有一种独特的表达方式,即:"foo bar".

一旦我们有了这样的表达式进行检查,自然该表达式也可以用作符号字面量。