簡體   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