Chr*_*Xue 48 ruby constructor return initializer new-operator
我想要的是:
obj = Foo.new(0) # => nil or false
Run Code Online (Sandbox Code Playgroud)
这不起作用:
class Foo
def initialize(val)
return nil if val == 0
end
end
Run Code Online (Sandbox Code Playgroud)
我知道在C/C++/Java/C#中,我们无法在构造函数中返回一个值.
但我想知道Ruby是否可行.
Jör*_*tag 79
在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
Run Code Online (Sandbox Code Playgroud)
但是,当然,你可以覆盖它来做你想做的任何事情.
初始化时如何返回nil?
我想要的是:
Run Code Online (Sandbox Code Playgroud)obj = Foo.new(0) # => nil or false这不起作用:
Run Code Online (Sandbox Code Playgroud)class Foo def initialize(val) return nil if val == 0 end end我知道在C/C++/Java/C#中,我们无法在构造函数中返回一个值.
但我想知道Ruby是否可行.
Ruby中没有构造函数这样的东西.在Ruby中,只有方法,它们可以返回值.
您看到的问题只是您想要更改一个方法的返回值,但是您要覆盖其他方法.如果要更改方法的返回值bar,则应覆盖bar,而不是其他方法.
如果要更改行为Foo::new,则应更改Foo::new:
class Foo
def self.new(val)
return nil if val.zero?
super
end
end
Run Code Online (Sandbox Code Playgroud)
但请注意,这是一个非常糟糕的主意,因为它违反了合同new,即返回完全初始化的,完全正常运行的类实例.
Gar*_*eth 45
这两种方法之间存在重要差异.
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
Run Code Online (Sandbox Code Playgroud)
用法示例:
obj = Foo.init(0)
=> nil
obj = Foo.init(5)
=> #<Foo:0x00000002970a98>
Run Code Online (Sandbox Code Playgroud)
想做
class Foo
def initialize(val)
return nil if val == 0
end
end
Run Code Online (Sandbox Code Playgroud)
会导致代码不一致。
如果你有
class Foo
def initialize(val)
return nil if val == 0
@val = val
@bar = 42
end
end
Run Code Online (Sandbox Code Playgroud)
如果你这样做了,你想得到什么Foo.new(1)?你想要42( 的返回值Foo#initialize),还是一个foo对象?如果你想foo为对象Foo.new(1),那么为什么你会希望return nil做Foo.new(0)回零?