ruby – “A级之间的差异; B级“和”A类:: B“
有什么区别:
class A class B end end 和 class A end class A::B end 更新:这两种方法并不完全相同. 在第二种方法中,B无法访问A中定义的常量. 此外,正如Matheus Moreira所说,在第二种方法中,必须在定义A :: B之前定义A. 还有什么其他差异? 解决方法
在Ruby中,模块和类分别是
Module 和
Class 类的实例.它们从它们被赋予的常量中得出它们的名称.当你写:
class A::B # ... end 你是在写作: A::B ||= Class.new do # ... end 哪个是有效的常量赋值语法,并假设A常量已正确初始化,并且它指的是模块或类. 例如,考虑如何定义类: class A # ... end 实际发生的是: Object::A ||= Class.new do # ... end 现在,当你写: class A class B # ... end end 实际发生的事情如下: (Object::A ||= Class.new).class_eval do (A::B ||= Class.new).class_eval do # ... end end 这是正在发生的事情,按顺序: >除非已初始化,否则新的Class实例将被赋予Object的A常量. 这样可以在尝试定义任何内部类之前确保所有外部类的存在. 范围也有变化,允许您直接访问A的常量.相比: class A MESSAGE = "I'm here!" end # Scope of Object class A::B # Scope of B puts MESSAGE # NameError: uninitialized constant A::B::MESSAGE end # Scope of Object class A # Scope of A class B # Scope of B puts MESSAGE # I'm here! end end 根据this blog post,Ruby核心团队将“当前类”称为cref.不幸的是,作者没有详细说明,但正如他所指出的那样,它与自我的背景是分开的. As explained here,cref是一个链表,表示模块在某个时间点的嵌套.
正如其他人所说,他们是表达同一事物的不同方式. 然而,有一个微妙的区别.当你编写A :: B类时,你假设已经定义了A类.如果没有,您将获得NameError,并且根本不会定义B. 编写正确嵌套的模块: class A class B end end 在尝试定义B之前确保A类存在. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |