在 ruby​​ 中创建匿名类

Posted

技术标签:

【中文标题】在 ruby​​ 中创建匿名类【英文标题】:Creating anonymous classes in ruby 【发布时间】:2021-11-18 10:45:53 【问题描述】:

根据示例中的“well ground ruby​​ist”,c“包含”或“指向”一个匿名类。我是对的,C 不是匿名类吗?这真的有点令人困惑。

    >> c = Class.new
    => #<Class:0x0000000006c4bd40>
    >> o1 = c.new
    => #<#<Class:0x0000000006c4bd40>:0x0000000006b81ec8>
    >> o1.class
    => #<Class:0x0000000006c4bd40>
    >>
    >> C = Class.new
    => C
    >> o2 = C.new
    => #<C:0x0000000006494480>
    >> o2.class
    => C

【问题讨论】:

【参考方案1】:

Class.new 创建一个新的匿名(未命名)类

c = Class.new 创建一个新的匿名类并将其分配给 局部变量 c

C = Class.new 创建一个新的匿名类并将其分配给 constant C

虽然两个赋值看起来几乎相同,但有一个微妙但重要的区别:将匿名类分配给 constant 将该类的 name 设置为常量的名称:

c = Class.new
c.name #=> nil

C = Class.new
C.name #=> "C"

Class.new 的文档中也提到了这一点:

您可以通过将类对象分配给常量来为类命名。

此时,该类不再是匿名的。它现在有了一个名称,我们可以使用该名称以常量C 的形式引用它。

【讨论】:

谢谢,就是这样! 可能值得注意的是,Module#const_set 可用于将匿名类 c = Class.new 分配给常量:Object.const_set('C', c); C == c #=&gt; true; C.name #=&gt; "C" @Cary:即使这样也有效:&gt;&gt; c = Class.new; =&gt; #&lt;Class:0x000000000681d9d0&gt; &gt;&gt; C = c; =&gt; C &gt;&gt; c.name; =&gt; "C"【参考方案2】:

“匿名”或“命名”类的概念在 Ruby 中没有真正意义。类只是一个对象,就像任何其他对象一样。我们也没有“匿名”或“命名”整数或字符串。类只是一个像整数或字符串一样的对象:它可以从方法返回,可以分配给局部变量、实例变量、类变量、全局变量或常量。

这与 Java 等具有主格类型系统的编程语言不同,后者有或没有名称的类型会产生很大的不同。

理解这一点非常重要:一个类只是一个对象,它恰好是Class 类的一个实例。没什么特别的。它只是一个像整数、字符串或数组这样的对象。

什么类(实际上是模块),是一个名为Module#name 的方法,但同样,该方法并没有什么特别之处。您也可以将#name 方法添加到您自己的类中。

唯一的特别之处在于,当一个类(实际上是一个模块)被赋值时(无论是使用赋值运算符=,还是反射性地使用Module#const_set方法),第一次到一个常量,那个常量的路径变成了Module#name的返回值:

a = Module.new
a.name #=> nil

b = a
b.name #=> nil

module A; module B; module C; end end end

A::B::C.const_set(:D, b)

a.name #=> 'A::B::C::D'

A::B::C::D = nil
A::B::C.send(:remove_const, :D)
A::B::C = nil
A::B.send(:remove_const, :C)
A::B = nil
A.send(:remove_const, :B)
A = nil
Object.send(:remove_const, :A)

a.name #=> 'A::B::C::D'

因此,如您所见,“匿名”和“命名”之间的区别实际上是不存在的,即使您可以构造一个有意义的定义,那么区别仍然无关紧要。

【讨论】:

以上是关于在 ruby​​ 中创建匿名类的主要内容,如果未能解决你的问题,请参考以下文章

你能在 Swift 中创建匿名内部类吗?

Ruby 中的匿名类

双括号初始化和“某种”静态匿名类

如何在kotlin中的匿名类中获取父类[重复]

java基础15 内部类(成员内部类局部内部类)和匿名内部类

匿名内部类