0

我一直在阅读一本 Ruby 书籍,其中我遇到了以下代码来描述符号

def walk(direction)
  if direction == :north
    # ...
  end
end

我尝试并未能创建类似的方法(其中与符号进行比较,例如

direction == :north

因为大多数时候我都看到使用了类似的符号param[:name],所以在我的代码中我尝试:north = 1 or :favourite = 'ruby'了但遇到了语法错误。

是否真的可以单独使用符号(没有哈希)进行这样的比较,即而不是

if "ruby" == param[:name]
end

if "ruby" == :name
end

我不确定我是否清楚地表达了这个问题,如果没有,我将尝试改写它。

4

2 回答 2

4

我看到了对符号是什么以及它们的目的的误解。

if direction == :north

在这一行中,direction是一个变量(它可以保存任何值)并且:north是一个(它可以分配给变量)。

尝试这样做:

:north = 1

就像尝试做

2 = 1

当然,这没有任何意义。

于 2013-08-28T17:06:20.560 回答
2

符号很像标识符,或特殊版本的字符串。

使用字符串,您可以拥有

str1 = 'SYM'

str2 = 'symbol'
str2 = str2[0,3].upcase

现在在内存的不同位置有两个相同的字符串。Ruby 必须比较所有要评估的字符str1 == str2

然而符号是独一无二的——你不能对它们进行字符操作,如果你有

sym1 = :SYM
sym2 = :SYM

那么只需进行一次比较即可测试它们的相等性。如果我们查看字符串和符号的对象 ID,就会清楚地证明这一点

puts str2.object_id
puts str1.object_id

puts sym1.object_id
puts sym2.object_id

puts str1.to_sym.object_id
puts str2.to_sym.object_id

输出

22098264
22098228
203780
203780
203780
203780

因此,这两个字符串具有不同的对象 ID,而这两个符号实际上是同一个对象。即使将两个字符串转换为符号也会给出相同的对象 ID,因此只有一个 :SYM.

因为符号是价值:north = 1,所以像写一样写是没有意义的'north' = 1

将字符串与符号进行比较,'north' = :north总是会返回false,因为它们是不同的对象类。

param[:name]仅因为您可以使用任何 object索引散列而起作用。(你可以说param[Object.new] = 1。)它不同于写param['name'](用文字字符串索引散列)或param[name](用变量的内容name索引散列)。

这回答了你的问题了吗?

于 2013-08-28T17:12:27.063 回答