所有
我正在尝试调整一些Ruby代码以在C#中工作,但C#不提供与Ruby相同的可用赋值语法
以下是我尝试改编的一些Ruby代码:
x, x1 = x1, x-q*x1
y, y1 = y1, y-q*y1
a, b = b, a-q*b
所以,我接受了它并做了这个,但我得到的结果与上面不同:
x = x1
x1 = x-q*x1
y = y1
y1 = y-q*y1
a = b
b = a-q*b
Ruby如何评估作业?为什么当我将多个任务分配到单个分配中时,结果会有所不同?
答案 0 :(得分:2)
Ruby首先评估RHS上的每个表达式,然后将它们分配给repsective LHS变量。
这是(基本上)Ruby如何评估第三行a, b = b, a-q*b
:
temp1 = b
temp2 = a-q*b
a = temp1
b = temp2
a = 5
,b = 7
和q = 10
的示例:
a, b = (7), (5 - 10*7)
产量
a == 7
b == -65
如您所见,在评估使用它的RHS表达式之前,没有值a
或b
从其初始值更改。
与C#代码中的内容形成对比:
a = b // a is changed BEFORE evaluating the value
// that will be put into b
b = a-q*b // The value of a has already been changed:
// this is now the same as b = b-q*b, which is not intended
使用与上述相同的值的示例结果:
a == 7
b == 7 - 10*7 == -63 // Not what we want...
要获得正确的结果,请在此答案的顶部使用带有临时变量的多行分配:
temp1 = b // 7
temp2 = a-q*b // 5 - 10*7 == -65
a = temp1 // 7
b = temp2 // -65
答案 1 :(得分:1)
Ruby在重新分配变量之前评估赋值的右侧。为了使其更加明确,它正在做这样的事情:
new_x, new_x1 = old_x1, old_x-q*old_x1
这导致:
new_x = old_x1
new_x1 = old_x-q*old_x1
但你正在做的是:
new_x = old_x1
new_x1 = new_x-q*old_x1 (= old_x1 - q * old_x1 = (1 - q) * old_x1)
因此结果不同。
答案 2 :(得分:0)
行x, x1 = x1, x-q*x1
意味着x和x1基本上会同时分配,但是您的C#变体不会考虑这一点。在您的c#代码中,x将在x1之前分配,因此x1将被分配x1-q*x1
而不是x-q*x1
,因为x此时已经被指定为x1。
可能的通用C#解决方案
tempX = x1
tempX1 = x-q*x1
x = tempX
x1 = tempX1
答案 3 :(得分:0)
问题在于,在作业中
x, x1 = x1, x-q*x1
Ruby在执行任一任务之前评估右侧的两个表达式。但是如果你写的话
x = x1
x1 = x-q*x1
然后因为第一个语句修改了x
的值,表达式x-q*x1
的值也发生了变化。
您需要使用临时变量,例如
newx = x1
x1 = x-q*x1
x = newx
以避免过早评估表达式的影响。