如何在ruby中拥有多个构造函数?
我想在Ruby中有多个构造函数。我知道我必须使用self方法,但问题是我不知道如何实现它们。例如:如何在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赋值。在第二
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可能只需要一些默认选项。特定组合的特定行为可能不在其要求中。