Dlean Jeans
Dlean Jeans

Reputation: 996

Assign variables value through array in Haxe?

How to assign variables a, b, c and d values to 1, 2, 3 and 4 through an array?

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

Upvotes: 4

Views: 214

Answers (2)

Andy Li
Andy Li

Reputation: 6034

The workaround provided by @Gama11 is correct that we need a container type, but the reasoning is wrong. The problem is not an effect of any optimization.

If we run the JS equivalent of the code in question, we will still get the same result:

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

In fact, this behaviour is the same in most other languages as well.

The reason is, the Array declaration takes the values of the input expressions instead of the references of them. That means a, b, c, and d are evaluated when setting array1.

This behaviour is the same for all expressions, except only for function:

/*
    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

Upvotes: 2

Gama11
Gama11

Reputation: 34138

The reason this doesn't work is that basic types like Int are immutable. In fact, the variables a, b, c and d might as well not even exist since they never change. If you look at the JS Source tab on try.haxe.org, you'll notice that they're not present in the output:

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);

This is an optimization of the analzyer.

You'll need some sort of container type to accomplish this, like a class or a typedef. Here's an example using the latter:

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
}

Upvotes: 2

Related Questions