在Ruby中,什么';这是';新';和';初始化';?如何在初始化时返回nil?
我想要的是:在Ruby中,什么';这是';新';和';初始化';?如何在初始化时返回nil?,ruby,constructor,return,new-operator,initializer,Ruby,Constructor,Return,New Operator,Initializer,我想要的是: obj = Foo.new(0) # => nil or false obj = Foo.new(0) # => nil or false 这不起作用: class Foo def initialize(val) return nil if val == 0 end end class Foo def initialize(val) return nil if val == 0 end end 我知道在C/C++/Java/C
obj = Foo.new(0) # => nil or false
obj = Foo.new(0) # => nil or false
这不起作用:
class Foo
def initialize(val)
return nil if val == 0
end
end
class Foo
def initialize(val)
return nil if val == 0
end
end
我知道在C/C++/Java/C#中,我们不能在构造函数中返回值
但是我想知道在Ruby中是否有可能。你可以这样做:
class Foo
def self.init(val)
new(val) unless val == 0
end
def initialize(val)
#...
end
end
class Foo
def initialize(val)
@val = val
return nil if @val == 0
end
end
obj = Foo.new(0)
Output:-
=>#<Foo:0x1243b8 @val=0>
用法示例:
obj = Foo.init(0)
=> nil
obj = Foo.init(5)
=> #<Foo:0x00000002970a98>
obj=Foo.init(0)
=>零
obj=Foo.init(5)
=> #
这两种方法之间有重要区别
new
是一个类方法,它通常创建类的实例(这处理一些棘手的事情,比如分配Ruby屏蔽的内存,这样你就不必太脏)
然后,initialize
,一个实例方法,告诉对象根据请求的参数设置其内部状态
根据需要,可以覆盖其中任何一个。例如,Foo.new
可能实际创建并返回foosublass
的实例,如果它需要足够聪明才能这样做的话
然而,通常最好将这样的用例委托给其他类方法,这些类方法更明确地说明它们的作用,例如Foo.relating_to(bar)
。打破其他人对new
等方法应该做什么的期望会让人们感到困惑,而不是从长远来看对他们有帮助
作为一个例子,请看一下单例
,一个只允许特定类的一个实例存在的模块的实现。它使new
方法私有,并公开一个instance
方法,该方法返回对象的现有实例,如果尚未创建该对象,则调用new
在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
obj = Foo.new(0) # => nil or false
这不起作用:
class Foo
def initialize(val)
return nil if val == 0
end
end
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
但是,请注意,这是一个非常糟糕的主意,因为它违反了new
的约定,即返回一个完全初始化的、功能完整的类实例。想要这样做吗
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)
return nil?只需创建如下对象变量即可解决此问题:
class Foo
def self.init(val)
new(val) unless val == 0
end
def initialize(val)
#...
end
end
class Foo
def initialize(val)
@val = val
return nil if @val == 0
end
end
obj = Foo.new(0)
Output:-
=>#<Foo:0x1243b8 @val=0>
class-Foo
def初始化(val)
@瓦尔=瓦尔
如果@val==0,则返回nil
结束
结束
obj=Foo.new(0)
输出:-
=>#
不同计算机的输出不同 如果这是一个健全的检查,一个更友好的方法是引发一个异常,解释为什么不继续初始化。返回nil只会造成(严重的)混乱。没有人会期望新实例化的对象为nil;)
C
中没有构造函数。@d11wtq语句的显著例外是NilClass.new()
。您应该将@Jörg W Mittag的答案标记为正确答案。在您的示例中,这是否也调用new?如果您指的是我们使用0调用init
时的示例,则否,不会调用new
。self
在Foo
中。尝试类Foo;p self end#=>Foo
您是否愿意为OP提供一个设计更好的解决方案,而不是简单地说事情不好?也许有点像梅茨的模式?验证器?等