+ =运算符似乎修改冻结的字符串
我正在使用ruby冻结法。 就冻结的定义而言,它会冻结调用它的对象的值。 我们无法在其后修改该对象的值。 我必须完成相同的任务,我有一个对象,我正在执行以下代码
a = "Test" a.freeze a += "this string" puts a
这给出了如下输出:
Test this string [Finished in 0.0s]
为什么要修改冻结的字符串?
什么都没有修改你的冷冻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 +=
...行之前和之后检查a.object_id
来validation这是您的情况。
冻结方法阻止您更改对象,它将对象转换为常量 。
s1 = "its testing" s1.freeze puts "Object ID ===", s1.obejct_id
因此,在冻结对象后,尝试修改它会导致TypeError。
s1 << "testing again"
它会给出,RuntimeError:无法修改冻结的String
但,
冻结操作对象引用 ,而不是变量
s1 += "New Testing" puts "Object ID ===", s1.obejct_id
将指向评估到新对象并检查其对象ID。
有关详细信息,请参阅此站点http://rubylearning.com/satishtalim/mutable_and_immutable_objects.html