我的代码有问题
def foo
var_original = var
while something
answer = modify! var #here we modify var in while loop
end
print var_original
answer
end
//var_original是我的代码中的矩阵对象
var_original 以某种方式返回 var 的值,即使分配后从未调用过它的功能。
我的目标是让var
等于返回answer
之前的开始。我想做var = var_original
,但只是意识到var_original
也以某种方式完全没有理由发生了变化。
有了这个问题,我提出了一个问题,我是否可以设置var_original
以锁定进行修改。我在论坛上使用$ global_variables找到了答案,但是在我将var_original
变成$var_original
后,它们没有解决我的问题。
还有其他可能的解决方案可以锁定var_original
进行修改吗?这是我的代码(很确定整个部分不是真正需要的,只是要证明我在其他任何地方都不会调用original_map
(。
def solve(minemap, miner, exit)
original_map = minemap
origins = miner
list = []
while true
break if miner == exit
if minemap[miner["x"]][miner["y"]].class == TrueClass
possibles = find_possibles(minemap, miner)
minemap[miner["x"]][miner["y"]] = [true, nil, possibles]
elsif minemap[miner["x"]][miner["y"]].class == Array
if minemap[miner["x"]][miner["y"]][1] == nil
miner = charge!(minemap, miner, list)
else
temp_miner = miner
teleport?(minemap, miner, list)
if temp_miner == miner && minemap[miner["x"]][miner["y"]][2] == 0
minemap[miner["x"]][miner["y"]] = false
end
end
else
miner = origins
end
end
print original_map #Prints minemap, but it should be original_map (crying)
puts
list
end
def find_possibles(minemap, miner)
possibles = []
if !minemap[miner["x"]][miner["y"] + 1].nil?
possibles << "down" if minemap[miner["x"]][miner["y"] + 1] == true && miner["y"] + 1 < minemap.size
end
if !minemap[miner["x"]][miner["y"] - 1].nil?
possibles << "up" if minemap[miner["x"]][miner["y"] - 1] == true && miner["y"] - 1 >= 0
end
if !minemap[miner["x"] - 1].nil?
possibles << "left" if minemap[miner["x"] - 1][miner["y"]] == true && miner["x"] - 1 >= 0
end
if !minemap[miner["x"] + 1].nil?
possibles << "right" if minemap[miner["x"] + 1][miner["y"]] == true && miner["x"] + 1 < minemap.size
end
possibles
end
def charge!(minemap, miner, list)
temp = minemap[miner["x"]][miner["y"]][2].shift
list << temp
minemap[miner["x"]][miner["y"]][1] = temp
case temp
when "down"
miner["y"] += 1
when "up"
miner["y"] -= 1
when "right"
miner["x"] += 1
when "left"
miner["x"] -= 1
end
miner
end
def teleport?(minemap, miner, list)
temp = minemap[miner["x"]][miner["y"]][1]
list << temp
case temp
when "right"
return miner if minemap[miner["x"]][miner["y"] + 1] == false
miner["x"] += 1 if minemap[miner["x"]][miner["y"] + 1][2].size > 0
when "left"
return miner if minemap[miner["x"]][miner["y"] - 1] == false
miner["x"] -= 1 if minemap[miner["x"]][miner["y"] - 1][2].size > 0
when "up"
return miner if minemap[miner["x"] - 1][miner["y"]] == false
miner["y"] -= 1 if minemap[miner["x"] - 1][miner["y"]][2].size > 0
when "down"
return miner if minemap[miner["x"] + 1][miner["y"]] == false
miner["y"] += 1 if minemap[miner["x"] + 1][miner["y"]][2].size > 0
end
miner
end
minemap = [[true, false],
[true, true]]
puts solve(minemap, {'x'=>0,'y'=>0}, {'x'=>1,'y'=>0}) #== ['right']
就像我在评论中提到的那样,您将希望var_original
成为var
的深副本。例如,您将执行以下操作:
var_original = Marshal.load(Marshal.dump(var))
这样,每当您更改var
时,var_original
都不会更改。
您的心理模型中缺少一件事。var
不是对象。它是对象的参考。
var_original = var
使var_original
指向var
指向的内存中相同对象。由于现在可以通过任何一个引用访问该对象,因此,如果您通过var
更改它,则可以通过var_original
看到更改。您想要的称为"深层复制/克隆"。查找。
或简单地做
var_original = var.dup
很可能会起作用。