Freezing 一个对象(.freeze)使其不可变 — 它不能再被修改。常见用法是冻结字符串字面量,这改进了性能(字符串被重用而不是重新分配)并防止意外变更。现代 Ruby 鼓励使用冻结字符串。
freeze 使对象不可变
config = { }.freeze
config[] =
= .freeze
str = .freeze
str.frozen?
str <<
.freeze 防止对对象的任何进一步修改 — 对于不应该改变的常量和共享数据很有用(防止意外变更 bug)。
# WITHOUT frozen string literals: each "hello" creates a NEW string object
1000.times { x = "hello" } # 1000 separate string objects allocated! (GC pressure)
# WITH frozen string literals: identical literals are REUSED (one shared object)
1000.times { x = "hello" } # reuses the SAME frozen "hello" object → efficient
字符串字面量通常是可变的,所以每次出现都会分配一个新对象。冻结字符串字面量是不可变的并被重用 — 相同的字符串共享一个对象,减少分配和 GC 压力(在热代码中有明显的性能收益)。
# frozen_string_literal: true # ← magic comment at the TOP of the file
# now ALL string literals in this file are automatically frozen (immutable + reused)
def greet
"hello" # this literal is frozen → reused, not re-allocated
end
在文件顶部添加 # frozen_string_literal: true 会自动冻结其所有字符串字面量 — 这是推荐的现代做法,可提高性能并捕获意外变更。(要创建可变副本,使用 +"string" 或 .dup。)
理解对象冻结和冻结字符串字面量对于 Ruby 的性能和正确性都很有价值。Freezing(.freeze)使对象不可变,这对于保护常量和共享数据免受意外修改很有用 — 防止一类变更 bug(特别重要,因为 Ruby 字符串默认是可变的,可能被意外改变)。
最有影响力的应用是冻结字符串字面量,它解决了 Ruby 的真实性能特征:因为字符串字面量通常是可变的,每次出现像 "hello" 这样的字面量都会分配一个新对象,在热代码中这会产生显著的分配和 GC 压力。冻结字符串字面量是不可变的并被重用(相同的字面量共享一个对象),减少分配并提高性能 — 这是一个有意义的优化。
# frozen_string_literal: true 魔法注释(冻结文件中所有字符串字面量)是推荐的现代 Ruby 做法,它提供了这种性能收益并捕获意外字符串变更,而且它越来越常见(并将可能在未来 Ruby 版本中成为默认行为)。
理解冻结(常量和共享数据的不可变性)、冻结字符串字面量的性能收益(重用而不是重新分配,减少 GC 压力)以及魔法注释作为现代最佳实践,对于编写高性能、正确的 Ruby 代码很有价值。
由于字符串分配在 Ruby 中是一个显著的性能因素,并且冻结字符串字面量越来越成为性能和防止变更 bug 的标准实践,理解冻结和冻结字符串是重要的高级知识,反映了对 Ruby 性能优化和现代最佳实践的认识 — 区分了性能意识强的 Ruby 开发者,这是编写高效、健壮 Ruby 代码的相关主题。