我想要的是:
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
在 Ruby 中,' ' 和 ' '之间是什么关系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
但是你当然可以覆盖它来做任何你想做的事情。
初始化时如何返回零?
我想要的是:
obj = Foo.new(0) # => nil or false
这不起作用:
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
,即返回一个完全初始化的、功能齐全的类实例。
两种方法之间存在重要差异。
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>
想做
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
对象 for Foo.new(1)
,那么你为什么要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>
输出在不同的计算机中有所不同。