Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在ruby中拥有多个构造函数?_Ruby - Fatal编程技术网

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

如何在ruby中拥有多个构造函数?,ruby,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赋值。在第二

我想在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赋值。
我该怎么做呢?

您不能通过使用关键字参数来实现您想要的功能:

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>
class-MyClass
属性读取器:num1,:num2,:num3
def初始化(n1:nil,n2:nil,n3:nil)
如果n2.nil?
将“num2为零”
结束
如果n3.nil?
将“num3为零”
结束
@num1=n1 | | 0
@num2=n2 | | 0
@num3=n3 | | 0
结束
结束
MyClass.new(n1:1,n2:3)
#num3为零
# => 
MyClass.new(n1:4,n3:1)
#num2为零
# => 
自ruby 2.0以来,关键字参数一直可用。例如,Google或see可获取有关关键字参数的更多信息

如果希望保持接近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-MyClass
属性读取器:num1,:num2,:num3
def初始化(n1=0,n2=0,n3=0)
@num1=n1
@num2=n2
@num3=n3
结束
def自呼(n1:nil,n2:nil,n3:nil)
如果n2.nil?
将“num2为零”
结束
如果n3.nil?
将“num3为零”
结束
新的n1、n2、n3
结束
结束
MyClass.(n1:1,n2:3)
#num3为零
# => 
MyClass.(n1:4,n3:1)
#num2为零
# => 
请注意类名后的“.”


另一种选择是使用
def self.[](…)
而不是
def self.call(…)
,并让您的调用使用
MyClass[…]
(类后无点)。

关于构造函数的Ruby语义(和Jörg关于这一点的评论通常完全正确),您说过要创建一个类,在该类中,您为该类的不同实例中的不同属性赋予值,而不是为任何给定实例中的所有属性赋予值

您不必使用“self方法”(Ruby称之为“class方法”)来实现这一点,当然也不需要“多个构造函数”来实现这一点。只需为它们中的每一个指定一个默认值
nil
。与您已经拥有的非常相似:

def initialize(n1 = nil, n2 = nil, n3 = nil)
  @num1 = n1
  @num2 = n2
  @num3 = n3
end
现在,如果在初始化实例时不设置它们,那么它们的值将是
nil
,如果需要,可以在方法中测试


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

要动态类构造函数,我认为您还需要动态实例变量的属性访问器。
因为我们需要知道初始化了哪些实例变量,所以我们应该在
initialize
block中声明
attr\u accessor

我已经检查过了,效果很好,您可以在这里尝试一下:

类多重构造函数
def初始化(args={})
各参数均为| k,v|
实例变量集(“@#{k}”,v)
self.class.send(:attr_访问器,*args.keys)
结束
结束
结束
在初始化构造函数之后,您可以获取或设置任何实例变量

m = MultipleConstructors.new(a: 1, c: 4)
m2 = MultipleConstructors.new(d: 'blah', e: 100)
m3 = MultipleConstructors.new(f: true)
或者您可以初始化任何您想要的构造函数…

参考:

在您的情况下,您将所有n1、n2、n3的值设置为0。我认为告诉我们大局是明智的;你的目标是什么。你能更准确地说出你想要实现什么吗?Ruby中没有“构造器”这样的东西,所以不清楚您的实际目标是什么。另外,请注意,您的代码中有两个名称相同的方法,因此后者将简单地覆盖前者。(你应该总是打开警告,它实际上会告诉你,在这种情况下,你正在覆盖一个方法!)我认为它们指的是他在问题中发布的构造实例的东西。下面是你要问的问题,但现在是一个务实的问题:你如何区分这两种情况?也就是说,如果我调用
MyClass(1,2)
,那么决定
1
是绑定到
n1
还是
n2
?除了执行
@num1=n1 | | 0
之外,您还可以在参数中将默认值设置为
0
,而不是使用
nil
def初始化(n1:0,n2:0,n3:0)
@3limin4t0r您可以,但这会破坏它。初始化器不知道
MyClass.new(n1:1,n2:0,n3:2)
MyClass.new(n1:1,n3:3)
之间的区别。尝试一下,您将看到这两个示例不再触发
num2为nil
num3为nil
。是的,但OP可能只需要一些默认选项。特定组合的特定行为可能不在其要求中。