Interesting behaviour when using for-in constructs in CFScript
I noticed something interesting when using for-in
constructs in cfscript: It appears that the variable in struct
argument in the for(in)
loop is set as an independent variable, and has no reference to its parent array key.
If you run the following code you will see the array doesn't change on output. The variable local.i
inside the loop is being assigned the new value, but the array remains unchanged.
function arrayTest()
{
local.foo = ["bar-one","bar-two", "bar-three"];
for (local.i in local.foo)
{
local.i = "I am #local.i#";
// Dump local.i; its output will be 'I am bar-[one[two]] etc...'
}
// Dump local.i; its output will as above
// Dump the array; its keys remain unchanged: "bar-one, bar-two, -bar-three"
writeDump(local.foo);
}
So why is this? I know arrays are passed by reference in CF, but I'm not passing an array here. I'm just using one in a for-in
construct. There is a difference, no?
It's a bit misleading to call the argument variable in structure.
I see local开发者_如何学运维.i
as a shortcut to local.foo[ local.i ]
. It sounds like the var is indeed the array key and we can modify it. The solution here is to use a plain for()
loop, instead.
I would not expect the underlying array to change unless i
was a complex object of some sort or something passed by reference. For example if foo were
local.foo = [{a="b"},{a="c"}];
then modifying local.i.a = "I am key #local.i.a#";
would modify the object within the array, and those changes would be reflected in your dump.
Update:
Ultimately this comes down to pointers or references. In loose terms, local.i
is just a pointer to objects within the array. So resetting local.i
just points that variable at some other object in memory. It has no impact on the array. Notice the change in hashcode value?
// example
local.foo = [ "bar-one" ];
for (local.i in local.foo)
{
WriteOutput("local.i (before) =#local.i.hashCode()#<br>"); //-335192660
WriteOutput("local.foo[1] = #local.foo[1].hashCode()#<br>");//-335192660
local.i = "I am key #local.i#";
WriteOutput("local.i (after) = #local.i.hashCode()#<br>"); //1075915694
}
writeDump(local.foo);
精彩评论