Ruby 和 Java 的 final 关键字中的常量

Constants in Ruby and Java's final keyword

我有以下变量

CONSTANT =5 

我想测试常量在 Ruby 中的工作原理并惊讶地发现以下内容:

CONSTANT = 6

..导致 CONSTANT 实际上被警告覆盖。我来自 java 背景,其中常量就是常量,因此我对 Ruby 如何完成事情感到有点困惑。

我的问题是是否有任何方法可以模仿 Ruby 中 java 的最终关键字,从而不允许用户更改变量的值?

就像 Ruby 中的许多事情一样,没有 "final",事情本质上是动态的,绝对阻止人们做事永远不会真正发生。你可以让它变得困难。

需要注意的一件事是 Ruby immutableconstant 之间的区别。常量是一个变量,它在重新分配时会产生警告,仅此而已,没有什么可以阻止您修改它。为了防止修改,您必须 "freeze" 有问题的对象,尽管与 Ruby 中的所有内容一样,这只是一个可以被对象忽略的请求。

通常您会看到这样的代码:

ADMIN_USER_TYPE = 'Admin'.freeze

或者这样:

USER_TYPES = %w[
  Admin
].freeze

freeze 调用是为了捕获列表可能被某种方法意外破坏的情况。它并不能绝对防止这种情况,它更像是一种安全措施。考虑这段代码:

def user_labels(types)
  types.map! { |t| [ t, t.downcase.to_sym ] }
end

此处错误的 map! 调用会产生重写原始数组的效果。如果您使用一次性参数调用它,这很好:

user_labels(%w[ Admin Test ])

当您使用常量时,您将永久修改它,这将导致它在每次调用时都被反复修改,从而造成混乱。 freeze 标志会在此处触发警告并阻止其发生。

所以简短的回答是:不。长的回答是你必须遵守纪律,如果你有足够的决心,语言不会阻止你这样做。注意警告并认真对待。