繁体   English   中英

如何在 ruby 中拥有多个构造函数?

[英]How can I have more than one constructor in ruby?

我想在 Ruby 中有多个构造函数。 我知道我必须使用 self 方法,但问题是我不知道如何实现它们。 例如:

def initialize(n1 = 0,n2 = 0,n3 = 0)
  @num1 = n1
  @num2 = n2
  @num3 = n3
end

def self.MyClass(num1, num3)
...
end

def self.MyClass(num2,num3)
 ...
end

所以在第一种情况下,我想做的是只给 num1 和 num3 一个值,而不是给 num2。 在第二种情况下,我只想给 num2 和 num3 赋值,而不是给 num1。 我怎样才能做到这一点?

难道你不能通过使用关键字 arguments 来实现你想要的:

class MyClass
  attr_reader :num1, :num2, :num3
  def initialize(n1: nil, n2: nil, n3: nil)
    if n2.nil?
      puts 'num2 is nil'
    end
    if n3.nil?
      puts 'num3 is nil'
    end
    @num1 = n1 || 0
    @num2 = n2 || 0
    @num3 = n3 || 0
  end
end

MyClass.new(n1: 1, n2: 3)
# num3 is nil
# => <MyClass:0x0... @num1=1, @num2=3, @num3=0>

MyClass.new(n1: 4, n3: 1)
# num2 is nil
# => <MyClass:0x0... @num1=4, @num2=0, @num3=1>

关键字 arguments 自 ruby 2.0 起可用。 谷歌或查看例如这里有关关键字 arguments 的更多信息。

如果你想保持接近 MyClass() 语法,你可以这样设置:

class MyClass
  attr_reader :num1, :num2, :num3
  def initialize(n1 = 0, n2 = 0, n3 = 0)
    @num1 = n1
    @num2 = n2
    @num3 = n3
  end
  def self.call(n1: nil, n2: nil, n3: nil)
    if n2.nil?
      puts 'num2 is nil'
    end
    if n3.nil?
      puts 'num3 is nil'
    end
    new n1, n2, n3
  end
end

MyClass.(n1: 1, n2: 3)
# num3 is nil
# => <MyClass:0x0... @num1=1, @num2=3, @num3=nil>
MyClass.(n1: 4, n3: 1)
# num2 is nil
# => <MyClass:0x0... @num1=4, @num2=nil, @num3=1>

注意“。” 在 class 名称之后。

另一种选择是使用def self.[](...)而不是def self.call(...)并使您的呼叫使用MyClass[...] (课后没有点)。

除了关于构造函数的 Ruby 语义(以及 Jörg 对此的评论是完全正确的,像往常一样),您已经说过您想要创建一个 class 在其中您为 ZA2F2ED4F8EBC2CBB4C21 的不同实例中的不同属性赋值,而不是所有在任何给定的情况下。

您不必使用“self 方法”(Ruby 称它们为“类方法”)来做到这一点,当然也不需要“多个构造函数”来做到这一点。 只需给他们每个人一个默认值nil 与您已经拥有的非常相似:

def initialize(n1 = nil, n2 = nil, n3 = nil)
  @num1 = n1
  @num2 = n2
  @num3 = n3
end

现在,如果您在初始化实例时没有设置它们,它们的值将为nil ,如果需要,您可以在您的方法中进行测试。

您还没有真正解释您要解决的问题(您还没有说为什么要让某些实例具有某些属性而其他实例具有其他属性),因此我无法真正告诉您这是否是解决方案。 但这是做你说你想做的最简单的方法。 如果您解释为什么要这样做,也许我们可以想出更好的方法。

要动态化您的 class 构造函数,我认为您也需要动态attr_accessor实例变量。
因为我们需要知道初始化了哪些实例变量,所以我们应该在initialize块中声明attr_accessor
我已经检查过了,效果很好,你可以在这里试一试:

class MultipleConstructors
  def initialize(args={})
    args.each do |k,v|
      instance_variable_set("@#{k}", v)
      self.class.send(:attr_accessor, *args.keys)
    end
  end
end

然后您可以在初始化构造函数之后获取或设置任何实例变量。

m = MultipleConstructors.new(a: 1, c: 4)
m2 = MultipleConstructors.new(d: 'blah', e: 100)
m3 = MultipleConstructors.new(f: true)

或者你可以初始化任何你想要的构造函数......
参考: https://apidock.com/ruby/Module/attr_accessor

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM