我们可以从许多著名的存储库中轻松找到这种样式,例如机架,导轨等。

For example in rack:

PATH_INFO      = 'PATH_INFO'.freeze
REQUEST_METHOD = 'REQUEST_METHOD'.freeze
SCRIPT_NAME    = 'SCRIPT_NAME'.freeze
QUERY_STRING   = 'QUERY_STRING'.freeze
CACHE_CONTROL  = 'Cache-Control'.freeze
CONTENT_LENGTH = 'Content-Length'.freeze
CONTENT_TYPE   = 'Content-Type'.freeze

Another examle in rails:
HTTP_IF_MODIFIED_SINCE = 'HTTP_IF_MODIFIED_SINCE'.freeze
HTTP_IF_NONE_MATCH     = 'HTTP_IF_NONE_MATCH'.freeze
HTTP_IF_NONE_MATCH     = 'HTTP_IF_NONE_MATCH'.freeze

我不知道为什么这些常量字符串会被冻结。由于它们都是常量,因此只能有一个实例。当然,我们可以将"foo".freeze放在某个位置以引用相同的单例实例,但是人们通常会写一些像HTTP_IF_MODIFIED_SINCE这样的文字变量名称。

因此,我认为,尽管使用#freeze并没有任何区别,那么为什么人们冻结常量呢?

最佳答案

将值重新分配给已初始化的常量时,Ruby将显示警告是正确的:

> FOO = 'foo'
> FOO = 'bar'
# :2: warning: already initialized constant FOO
# :1: warning: previous definition of FOO was here
> FOO
# => "bar"

但是没有保护措施不能更改常量中的值。没有freeze的示例:
> FOO = 'foo'
> FOO[1] = '-'
> FOO
# => "f-o"

但是freeze允许保护常量的值不被更改。 freeze的示例:
> FOO = 'foo'.freeze
> FOO[1] = '-'
# => RuntimeError: can't modify frozen String

09-25 13:59