这个双冒号::是什么?例如Foo:酒吧。
我找到了一个定义:
::是一个一元操作符,允许在类或模块内定义的:常量、实例方法和类方法从类或模块外的任何地方访问。
如果你只能使用::来暴露任何东西,那么作用域(私有的,受保护的)有什么用呢?
这个双冒号::是什么?例如Foo:酒吧。
我找到了一个定义:
::是一个一元操作符,允许在类或模块内定义的:常量、实例方法和类方法从类或模块外的任何地方访问。
如果你只能使用::来暴露任何东西,那么作用域(私有的,受保护的)有什么用呢?
当前回答
Surprisingly, all 10 answers here say the same thing. The '::' is a namespace resolution operator, and yes it is true. But there is one gotcha that you have to realize about the namespace resolution operator when it comes to the constant lookup algorithm. As Matz delineates in his book, 'The Ruby Programming Language', constant lookup has multiple steps. First, it searches a constant in the lexical scope where the constant is referenced. If it does not find the constant within the lexical scope, it then searches the inheritance hierarchy. Because of this constant lookup algorithm, below we get the expected results:
module A
module B
PI = 3.14
module C
class E
PI = 3.15
end
class F < E
def get_pi
puts PI
end
end
end
end
end
f = A::B::C::F.new
f.get_pi
> 3.14
F继承自E,而B模块在F的词法范围内。因此,F实例将引用模块B中定义的常数PI。现在,如果模块B没有定义PI,那么F实例将引用超类E中定义的PI常量。
但是如果我们使用'::'而不是嵌套模块呢?我们会得到同样的结果吗?不!
通过在定义嵌套模块时使用名称空间解析操作符,嵌套模块和类不再在其外部模块的词法范围内。如下所示,在A::B中定义的PI不在A::B::C::D的词法范围内,因此当我们试图在get_pi实例方法中引用PI时,会得到未初始化的常量:
module A
end
module A::B
PI = 3.14
end
module A::B::C
class D
def get_pi
puts PI
end
end
end
d = A::B::C::D.new
d.get_pi
NameError: uninitialized constant A::B::C::D::PI
Did you mean? A::B::PI
其他回答
如果你只能使用::来暴露任何东西,那么作用域(私有的,受保护的)有什么用呢?
在Ruby中,所有内容都是公开的,并且可以从其他任何地方修改所有内容。
如果您担心可以从“类定义”之外更改类,那么Ruby可能不适合您。
另一方面,如果您对Java的类被锁定感到沮丧,那么Ruby可能是您正在寻找的对象。
::允许您访问在另一个类或模块中定义的常量、模块或类。它用于提供名称空间,以便不同作者的方法名和类名不会与其他类冲突。
当你在Rails中看到ActiveRecord::Base时,这意味着Rails有类似于
module ActiveRecord
class Base
end
end
例如,在ActiveRecord模块中一个名为Base的类,然后被引用为ActiveRecord::Base(你可以在Rails源代码ActiveRecord -n.n.n/lib/active_record/ Base .rb中找到这个)
::的常用用法是访问模块中定义的常量。
module Math
PI = 3.141 # ...
end
puts Math::PI
操作符不允许绕过标记为private或protected的方法的可见性。
::基本上是一个名称空间解析运算符。它允许您访问模块中的项,或类中的类级项。例如,假设你有这样的设置:
module SomeModule
module InnerModule
class MyClass
CONSTANT = 4
end
end
end
你可以通过SomeModule::InnerModule::MyClass::CONSTANT从模块外部访问CONSTANT。
它不会影响类中定义的实例方法,因为您可以使用不同的语法(点。)访问这些实例方法。
相关提示:如果你想回到顶层的命名空间,请执行:::SomeModule - Benjamin Oakes
module Amimal
module Herbivorous
EATER="plants"
end
end
Amimal::Herbivorous::EATER => "plants"
::用于创建作用域。为了从2个模块中访问Constant EATER,我们需要确定模块的范围以达到常数
简单来说,它是一个命名空间, 命名空间是模块、类、函数等的容器。同时也有助于解决名称冲突的问题。 在ruby中,你可以通过模块访问命名空间
module A
class Article
def Base
end
module B
end
end
所以要访问类Article,我们使用A::Article。 在某些情况下你会看到 答::文章<应用程序::Base 这意味着模块A的Article类继承了Application模块的基类。