Ruby类继承:什么是`<<`(double less than)?

Vol*_*ort 71 ruby

class << Awesomeness
Run Code Online (Sandbox Code Playgroud)

这是<<为了什么?我搜索了,但结果只告诉我字符串连接...

Rob*_*vis 133

虽然class << something正如其他人所说的那样是单例类的语法,但它最常用于在类定义中定义类方法.但这两种用法是一致的.这是如何做.

Ruby允许您通过执行以下操作向任何特定实例添加方法:

class << someinstance
  def foo
    "Hello."
  end
end
Run Code Online (Sandbox Code Playgroud)

foo为某个实例添加了一个方法,而不是它的类,而是一个特定的实例.(实际上,foo被添加到实例的"单例类"中,但这或多或少是一个实现怪癖.)执行上述代码后,您可以将方法foo发送到某个实例:

someinstance.foo   => "Hello."
Run Code Online (Sandbox Code Playgroud)

但是你不能将foo发送到同一个类的其他实例.这<<就是名义上的.但是人们更常用这个功能用于这样的句法体操:

class Thing
  def do_something
  end

  class << self
    def foo
      puts "I am #{self}"
    end
  end
end
Run Code Online (Sandbox Code Playgroud)

当这个代码 - 这个类定义 - 执行时,是什么self?这是班级Thing.这意味着class << self与"将以下方法添加到类Thing"相同.也就是说,foo是一种类方法.完成上述操作后,您可以执行以下操作:

t = Thing.new
t.do_something  => does something
t.class.foo     => "I am Thing"
t.foo           => NoMethodError: undefined method `foo'
Run Code Online (Sandbox Code Playgroud)

当你想到<<正在做的事情时,这一切都是有道理的.这是一种附加到特定实例的方法,在通常情况下,附加到的实例是一个类,因此块中的方法成为类方法.

简而言之,在类定义块中创建类方法是一种简洁的方法.另一种方法是这样做:

class Thing
  def self.foo
    # ...
  end
end
Run Code Online (Sandbox Code Playgroud)

一样.您的示例实际上是语法错误,但如果您了解如何<<使用实例和class关键字,您将知道如何更正它.

  • @Omega:是的,你会看到这个,例如,当你想要创建一个类方法的多个方法时,你不希望它们都以"self"为前缀.你可以把它们全部放在那个区块中而不用担心它. (5认同)
  • 真的很棒的答案! (3认同)

Zab*_*bba 19

<<"Singleton类定义"的语法.以下是 "典型"使用位置/方式的示例.

a = "abc"; a << "xyz"它是"附加数据"的语法(字符串,阵列等)

  • 在Ruby` <<中称为`铲运算符' (7认同)

And*_*imm 18

如果你想继承(根据你的问题标题),你想要一个<:

class Awesome < ParentAwesomeness
Run Code Online (Sandbox Code Playgroud)

您提供的代码不是有效的ruby:

class Awesomeness
end

class Awesome << Awesomeness
end

SyntaxError: (irb):3: syntax error, unexpected tLSHFT, expecting '<' or ';' or '\n'
Run Code Online (Sandbox Code Playgroud)