我正在使用红宝石冻结法。考虑到冻结的定义,它会冻结调用它的对象的值。我们无法在其后修改该对象的值。我必须完成相同的任务,我有一个对象,我正在执行以下代码
a = "Test"
a.freeze
a += "this string"
puts a
这给出了如下输出:
Test this string
[Finished in 0.0s]
为什么要修改我的冻结字符串?
答案 0 :(得分:49)
没有修改冻结的String
您正在使用
将a
重新分配给新的String
a += "this string"
在Ruby中内部与
相同a = a + "this string"
在Ruby中添加两个String对象时,它将创建一个包含结果的新String(这是+
运算符在支持它的大多数对象上的正常行为)。这使得原始的“Test”和“this string”值保持不变。原始的冻结字符串(包含“测试”)将保留在内存中,直到它被垃圾收集。它可以被收集,因为你丢失了对它的所有引用。
如果您尝试按原样修改对象:
a << "this string"
然后您应该看到错误消息RuntimeError: can't modify frozen String
基本上,您已将局部变量a
与其指向的String
对象混淆。可以随时重新分配局部变量,而与Ruby存储的对象无关。您可以通过在a.object_id
...行之前和之后检查a +=
来验证这是您的案例中发生的事情。
答案 1 :(得分:3)
冻结方法会阻止您更改对象,它会将对象转换为常量。
s1 = "its testing"
s1.freeze
puts "Object ID ===", s1.obejct_id
因此,在冻结对象后,尝试修改它会导致TypeError。
s1 << "testing again"
它会给出,RuntimeError:无法修改冻结的字符串
,但
冻结操作对象参考,而不是变量
s1 += "New Testing"
puts "Object ID ===", s1.obejct_id
将指向评估新对象并检查其对象ID。
有关详细信息,请参阅本网站, http://rubylearning.com/satishtalim/mutable_and_immutable_objects.html