在 Haxe 中通过数组分配变量值?

Assign variables value through array in Haxe?

如何将变量 abcd 值分配给 1234 通过数组?

var a:Int = 0, b:Int = 0, c:Int = 0, d:Int = 0;
var array1:Array<Int> = [a, b, c, d];
var array2:Array<Int> = [1, 2, 3, 4];

for (i in 0...4)
    array1[i] = array2[i]; //this does not work, it assigns array1's elements instead

trace(a); // this prints 0 instead of 1
trace(b); // 0 instead of 2
trace(c); // 0 instead of 3
trace(d); // 0 instead of 4

这不起作用的原因是像 Int 这样的基本类型是不可变的。事实上,变量 abcd 甚至可能不存在,因为它们永远不会改变。如果您查看 try.haxe.org 上的 JS 源选项卡,您会注意到它们不存在于输出中:

var array1 = [0,0,0,0];
var array2 = [1,2,3,4];
var _g = 0;
while(_g < 4) {
    var i = _g++;
    array1[i] = array2[i];
}
console.log(0);
console.log(0);
console.log(0);
console.log(0);

这是对分析器的优化。

您需要某种类型的容器来完成此操作,例如 classtypedef。这是使用后者的示例:

class Test {
    static function main() {
        var a:IntContainer = { value: 0 };
        var b:IntContainer = { value: 0 };
        var c:IntContainer = { value: 0 };
        var d:IntContainer = { value: 0 };

        var array1:Array<IntContainer> = [a, b, c, d];
        var array2:Array<Int> = [1, 2, 3, 4];

        for (i in 0...4)
            array1[i].value = array2[i];

        trace(a.value);
        trace(b.value);
        trace(c.value);
        trace(d.value);
    }
}

typedef IntContainer = {
    value:Int
}

@Gama11 提供的解决方法是正确的,我们需要一个容器类型,但推理是错误的。 问题不是任何优化的结果

如果我们运行 JS 等同于有问题的代码,我们仍然会得到相同的结果:

var a = 0, b = 0, c = 0, d = 0;
var array1 = [a, b, c, d];
var array2 = [1, 2, 3, 4];

for (var i = 0; i < 4; i++)
    array1[i] = array2[i];

console.log(a); // 0
console.log(b); // 0
console.log(c); // 0
console.log(d); // 0

事实上,这种行为在大多数其他语言中也是相同的。

原因是,Array 声明采用输入表达式的 values 而不是 references。这意味着在设置 array1.

时评估 abcd

此行为对于所有表达式都是相同的,只有函数除外:

/*
    variable
*/
var a = "A";
var b = a;
a = "B";
trace(b); // A

/*
    anon. object
*/
var a = "A";
var c = { _c: a };
a = "C";
trace(c._c); // A

/*
    Map
*/
var a = "A";
var d = ["_d" => a];
a = "D";
trace(d["_d"]); // A

/*
    function
    The function body is evaluated every time when it is called.
*/
var a = "A";
var f = function () return a;
a = "F";
trace(f()); // F <-- notice this