obj = Foo.new(0) # => nil or false
这不起作用:class Foo
def initialize(val)
return nil if val == 0
end
end
我知道在C/C++/Java/C#中,我们不能在构造函数中返回一个值。
但是我想知道在Ruby中是否可能。
obj = Foo.new(0) # => nil or false
这不起作用:class Foo
def initialize(val)
return nil if val == 0
end
end
我知道在C/C++/Java/C#中,我们不能在构造函数中返回一个值。
但是我想知道在Ruby中是否可能。
new
' 和 'initialize
' 之间的关系是什么?
new
通常会调用 initialize
。默认的 new
实现大致如下:class Class
def new(*args, &block)
obj = allocate
obj.initialize(*args, &block)
# actually, this is obj.send(:initialize, …) because initialize is private
obj
end
end
当然,您可以覆盖它以执行任何您想要的操作。
如何在初始化时返回nil?
我想要的是:
obj = Foo.new(0) # => nil or false
这不起作用:
在Ruby中并不存在所谓的“构造函数”。在Ruby中,只有方法存在,并且它们可以返回值。
class Foo def initialize(val) return nil if val == 0 end end
你遇到的问题简单来说就是想要改变一个方法的返回值,但是你却重载了另一个方法。如果你想改变bar
方法的返回值,你应该重载bar
而不是其他方法。
如果你想改变Foo::new
的行为,那么你应该改变Foo::new
方法:
class Foo def self.new(val) return nil if val.zero? super end end
请注意,这是一个非常糟糕的想法,因为它违反了
new
的契约,即返回一个完全初始化、完全运行的类实例。
self
是 Foo
。尝试 class Foo; p self end # => Foo
。 - Jörg W Mittag这两种方法存在重要的区别。
new
是一个类方法,通常用于创建该类的实例(它处理了像分配内存这样的棘手问题,Ruby 会屏蔽这些问题,以便您不必过于深入地了解细节)。
然后,initialize
是一个实例方法,告诉对象按照所请求的参数设置其内部状态。
这两个方法都可以根据您的需求进行重写。例如,如果需要聪明到能够执行此操作,Foo.new
可能实际上会创建并返回FooSubclass
的实例。
但通常最好将此类用例委托给其他类方法,这些类方法更明确地说明它们的作用,例如 Foo.relating_to(bar)
。打破其他人对诸如new
之类方法的期望,会让人们更加困惑,而不是在长远来看有所帮助。
例如,看看Singleton
的实现,这是一个允许特定类仅存在一个实例的模块。它将new
方法设为私有,并公开了一个instance
方法,该方法要么返回对象的现有实例,要么调用new
方法(如果尚未创建该实例)。
您可以这样做:
class Foo
def self.init(val)
new(val) unless val == 0
end
def initialize(val)
#...
end
end
使用示例:
obj = Foo.init(0)
=> nil
obj = Foo.init(5)
=> #<Foo:0x00000002970a98>
init
的例子,那么不,new
不会被调用。 - FlexoidWanting to do
class Foo
def initialize(val)
return nil if val == 0
end
end
如果你的代码不一致,那么会使代码变得混乱。
如果你有
class Foo
def initialize(val)
return nil if val == 0
@val = val
@bar = 42
end
end
如果你执行 Foo.new(1)
,你想得到什么返回值?你想要得到 42
(Foo#initialize
的返回值),还是想要得到一个 foo
对象?如果你希望执行 Foo.new(1)
后得到一个 foo
对象,那为什么你会期望 return nil
会使得 Foo.new(0)
返回 nil 呢?
通过简单地创建一个对象变量来解决:
class Foo
def initialize(val)
@val = val
return nil if @val == 0
end
end
obj = Foo.new(0)
Output:-
=>#<Foo:0x1243b8 @val=0>
输出结果在不同的计算机上会有所不同。
C
中没有构造函数。 - YoTengoUnLCDNilClass.new()
。 - Joe Atzberger