I am initializing an Array of Arrays with undef. Why does it give me an UndefRefError when accessing it, whereas an Array with undef does not? Also, did some behavior change? I seem to remember initializing Array of Arrays before and never having a UndefRefError before.
a = Array{Int64}(undef, 10)
b = Array{Array{Int64}}(undef, 10)
a[1] # No error
b[1] # UndefRefError
PS: performance issues or best practices asides. It seems that using fill to initialize Array of Arrays might be better, but I’m just wondering what’s happening in the above case.
When you use Vector{T}(undef, n), the uninitialized elements of the vector will be filled with random data (whatever happens to be in memory) if T is an isbits type. If T is not an isbits type, then you will get an UndefRefError if you try to access an uninitialized element, since the element hasn’t been initialized with a pointer to an instance of the non-isbits type.
As @Paul_Soderlind mentioned, fill is probably not the right tool, unless you want every field to have the same vector. An alternative is using a list comprehension:
b = [Vector{Int64}() for _ = 1:10]
But there is nothing wrong with creating a uninitialized Vector and then assign a inner Vector to each position before accessing it.
I’m curious why you were trying to avoid loops. This is a common heuristic from programmers coming from other languages since loops in those languages may be slow. Often in Julia, a properly written loop is often the fastest approach.
Purely for readability purposes, no other reason. Initializing a matrix (only once) doesn’t have to be too efficient, just readable so that was why. I agree tho, when it comes to performance I’ve found loops generally perform much better than map et al.