【问题标题】:Class variable returns empty after first run through a function首次运行函数后,类变量返回空
【发布时间】:2015-02-05 15:26:24
【问题描述】:

我正在用 Ruby 写一个mastermind game。到目前为止,我的代码位于here on github

我遇到的问题是:当我运行下面的函数时,在游戏开始时生成的实例变量@code在第一次运行函数后返回空。

我已经分配了一个局部变量 tempcode,@code 的值,所有的操作都是在函数内对 tempcode 进行的。我还为@code 分配了一个attr_reader,而不是一个attr_accessor。所以@code 不应该改变!

def compare_guess_to_code()
        correct_color = "1"
        correct_color_and_pos = "2"
        incorrect_color = "0"
        tempcode = @code
        a = 0
        @guess.length.times do #maybe a for loop that goes through both arrays simultaneously?
            case
            when @guess[a] == tempcode[a]
                feedback.push(correct_color_and_pos)
                tempcode.delete_at[a]
                @guess.delete_at[a]
            when guess[a] != tempcode[a]  && tempcode.include?(guess[a])
                feedback.push(correct_color)
                tempcode.delete_at[a]
                @guess.delete_at[a]
            when !(tempcode.include?(guess[a]))             
                feedback.push(incorrect_color)
                tempcode.delete_at[a]
                @guess.delete_at[a]
            else
                puts "Error"
            end             
        end
        feedback.sort!
        feedback.reverse!
        print "Feedback: #{feedback}"

    end

反馈正确返回,一切似乎都工作正常,在@code 清空之前,我不能多次执行比较功能。我怎样才能保持价值一致?

如果要运行程序进行测试,请使用 mastermind/lib/mastermind.rb。

【问题讨论】:

  • 这是一个引用,你的临时变量是对同一个数组的引用。你需要复制它。

标签: ruby arrays oop


【解决方案1】:

您分配数组tempcode = @code 并使用tempcode.delete_at[a] 修改它,这也会更改@code。要修复它,您可以使用

tempcode = @code.clone

这样@code就不会受到tempcode's变化的影响

【讨论】:

  • 谢谢,这行得通,但为什么呢?我对变量的理解是,如果你做 a = 8 b = a a = "eight" b 会返回 8 那么为什么这里有区别呢?
  • 发生的情况是该变量只存储对对象的引用,而不是对象本身。这里 code 和 tempcode 都指向同一个数组对象,更改 tempcode 将更新对象 code 指向的对象。在您的示例中,a 指向 8,b = a => b 也指向 8,a = "eight" => a 现在指向 "8",b 仍然指向 8。
  • 谢谢。你能推荐一些关于这个的阅读吗?到目前为止,我所使用的文本或教程都没有提到这种行为。
  • 我认为这很好地说明了它stackoverflow.com/questions/1872110/…我找不到任何其他教程,我实际上是根据我使用Java的经验知道的
【解决方案2】:

当您分配一个数组时,它只是复制引用并且它们都指向同一个引用。 因此,当您打印其中任何一个时,其中一个的变化就会反映出来。

orig_array = [1,2,3,4]<br>
another_array = orig_array

puts orig_array.unshift(0).inspect
puts another_array.inspect

输出:

[0, 1, 2, 3, 4]
[0, 1, 2, 3, 4]

为避免这种情况,您可以使用 Marshal 从原始数组复制,而不会影响复制到的对象。 原始数组中的任何更改都不会更改它所复制到的对象。

orig_array = [1,2,3,4]<br>
another_array = Marshal.load(Marshal.dump(orig_array))

puts orig_array.unshift(0).inspect
puts another_array.inspect

输出:

[0, 1, 2, 3, 4]
[1、2、3、4]

【讨论】:

    猜你喜欢
    • 2021-05-09
    • 2018-02-19
    • 1970-01-01
    • 2018-08-26
    • 1970-01-01
    • 2015-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多