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