Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Ruby中,什么';这是';新';和';初始化';?如何在初始化时返回nil?_Ruby_Constructor_Return_New Operator_Initializer - Fatal编程技术网

在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提供一个设计更好的解决方案,而不是简单地说事情不好?也许有点像梅茨的模式?验证器?等