新手入门:ruby 中的实例变量?

2024-03-04

请原谅这个新手问题,但为什么 @game_score 总是为零?

#bowling.rb

class Bowling
  @game_score = 0
    def hit(pins)
        @game_score = @game_score + pins
    end

    def score
        @game_score
    end
end

让我们看一下代码,好吗?

#bowling.rb

class Bowling
  @game_score = 0 # (1)

此时(1),我们仍然处于class Bowling。请记住:类与其他对象一样只是对象。所以,此时您正在分配0到实例变量@game_score 类对象的Bowling.

 def hit(pins)
  @game_score = @game_score + pins # (2)

现在(2),我们在一个实例方法 of the Bowling班级。即:这是一个属于instance of Bowling。所以,现在实例变量@game_score属于instance of the Bowling类,而不是类本身。

Since this实例变量从未被初始化为任何内容,它将计算为nil(在 Ruby 中,未初始化的变量总是计算为nil),因此计算结果为@game_score = nil + pins自从nil没有#+方法,这将导致NoMethodError引发异常。

 end
 def score
  @game_score # (3)

在这里(3),我们再次处于一个实例方法 of the Bowling班级。这将始终评估为nil,出于我上面概述的原因:@game_score从未初始化,因此它的计算结果为nil.

 end
end

我们可以利用Ruby的反射能力来看看到底发生了什么:

p Bowling.instance_variable_get(:@game_score) # => 0
b = Bowling.new
p b.instance_variable_get(:@game_score) # => nil

现在让我们向实例变量注入一个值:

b.instance_variable_set(:@game_score, 1)
p b.score # => 1
b.hit(3)
p b.score # => 4

因此,我们看到一切都按预期工作,我们只需要弄清楚如何确保实例变量得到初始化。

为此,我们需要编写一个初始化方法。奇怪的是,初始化方法实际上是私有的实例方法 called initialize。 (之所以initialize是实例方法而不是类方法,实际上很简单。 Ruby 将对象创建分为两个阶段:内存分配和对象初始化。内存分配是由一个class方法称为alloc对象初始化是由instance方法称为initialize。 (Objective-C 程序员会认识到这一点。)原因alloc是一个类方法只是因为此时执行中还没有实例。而原因是initialize是一个实例方法,对象初始化显然是每个对象的。为了方便起见,有一个标准工厂类方法称为new这两个都调用alloc and initialize为你。)

class Bowling
 def initialize
  @game_score = 0
 end
end

让我们测试一下:

c = Bowling.new
p c.score # => 0
c.hit(2)
p c.score # => 2

顺便说一句:只是一些小的 Ruby 风格提示:缩进是 2 个空格,而不是 1 个制表符。和你的hit更惯用的方法是@game_score += pins.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

新手入门:ruby 中的实例变量? 的相关文章

随机推荐