Reputation: 996
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
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
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