Reputation: 8566
take a look at this example:
julia> VERSION
v"0.4.0-rc1"
julia> foo = [1,2]
2-element Array{Int64,1}:
1
2
julia> baz = Array(Any,3)
3-element Array{Any,1}:
#undef
#undef
#undef
julia> for i = 1:3
foo[1] = -foo[1]
baz[i] = foo
println("loop",i)
println("foo: ",typeof(foo),"->",foo)
println("baz[",i,"]: ",typeof(baz[i]), "->", baz[i])
println("baz: ",typeof(baz),"->",baz)
end
loop1
foo: Array{Int64,1}->[-1,2]
baz[1]: Array{Int64,1}->[-1,2]
baz: Array{Any,1}->Any[[-1,2],#undef,#undef]
loop2
foo: Array{Int64,1}->[1,2]
baz[2]: Array{Int64,1}->[1,2]
baz: Array{Any,1}->Any[[1,2],[1,2],#undef]
loop3
foo: Array{Int64,1}->[-1,2]
baz[3]: Array{Int64,1}->[-1,2]
baz: Array{Any,1}->Any[[-1,2],[-1,2],[-1,2]]
the results are unexpected to me, i think baz
should be Any[[-1,2],[1,2],[-1,2]]
.
However, if foo
is not an array, the results are reasonable.
julia> foo = 1
1
julia> baz = Array(Any,3)
3-element Array{Any,1}:
#undef
#undef
#undef
julia> for i = 1:3
foo = -foo
baz[i] = foo
println("loop",i)
println("foo: ",typeof(foo),"->",foo)
println("baz[",i,"]: ",typeof(baz[i]), "->", baz[i])
println("baz: ",typeof(baz),"->",baz)
end
loop1
foo: Int64->-1
baz[1]: Int64->-1
baz: Array{Any,1}->Any[-1,#undef,#undef]
loop2
foo: Int64->1
baz[2]: Int64->1
baz: Array{Any,1}->Any[-1,1,#undef]
loop3
foo: Int64->-1
baz[3]: Int64->-1
baz: Array{Any,1}->Any[-1,1,-1]
my question is what happened here, what's the correct way to assign array in for-loop?
EDIT: i added baz = deepcopy(baz)
and everything goes fine. still want to know the reason.
Upvotes: 3
Views: 124
Reputation: 5325
This is a common trap, that arises becauses the array foo
is a binding. John Myles White has written a very nice blog post on this:
http://www.johnmyleswhite.com/notebook/2014/09/06/values-vs-bindings-the-map-is-not-the-territory/
By the way, you should try to avoid Any
arrays, which are slow. You can do this easily as follows:
Array(typeof(v), 3)
or just put the explicit type of v
, e.g.
Array(Vector{Int}, 3)
Here, Vector{Int}
is equivalent to (another name for) Array{Int, 1}
.
Also note that instead of all those println
s, you can just use the nice @show
:
julia> a = 3
3
julia> @show a
a = 3
3
@show
also returns the value shown. On previous versions of Julia, the output looked like a => 3
Upvotes: 4
Reputation: 5746
Julia has Noteworthy Differences from other Languages
e.g. unlike MATLAB Julia arrays are assigned by reference. A reference is an alias, or an alternate name to an existing variable. For example, suppose you make peter a reference (alias) to paul, you can refer to the person as either peter or paul.
After baz[i] = foo
, changing elements of foo
will modify baz[i]
as well.
Upvotes: 4