diff --git a/base/array.jl b/base/array.jl index dedc717b056d3..c190abac074e3 100644 --- a/base/array.jl +++ b/base/array.jl @@ -431,14 +431,74 @@ to_dim(d::Integer) = d to_dim(d::OneTo) = last(d) """ - fill(x, dims::Tuple) - fill(x, dims...) + fill(value, dims::Tuple) + fill(value, dims...) -Create an array filled with the value `x`. For example, `fill(1.0, (5,5))` returns a 5×5 -array of floats, with each element initialized to `1.0`. +Create an array of size `dims` with every element set to `value`. -`dims` may be specified as either a tuple or a sequence of arguments. For example, -the common idiom `fill(x)` creates a zero-dimensional array containing the single value `x`. +For example, `fill(1.0, (5,5))` returns a 5×5 array of floats, +with `1.0` in every location of the array. + +The dimension lengths `dims` may be specified as either a tuple or a sequence of arguments. +An `N`-length tuple or `N` arguments following the `value` specify an `N`-dimensional +array. Thus, a common idiom for creating a zero-dimensional array with its only value +set to `x` is `fill(x)`. + +Every element of the returned array is set to (and is thus [`===`](@ref) to) +the `value` that was passed; this means that if the `value` is itself modified, +all elements of the `fill`ed array will reflect that modification because they're +_still_ that very `value`. This is of no concern with `fill(1.0, (5,5))` as the +`value` `1.0` is immutable and cannot itself be modified, but can be unexpected +with mutable values like — most commonly — arrays. For example, `fill([], 3)` +places _the very same_ empty array in all three locations of the returned vector: + +```jldoctest +julia> v = fill([], 3) +3-element Vector{Vector{Any}}: + [] + [] + [] + +julia> v[1] === v[2] === v[3] +true + +julia> value = v[1] +Any[] + +julia> push!(value, 867_5309) +1-element Vector{Any}: + 8675309 + +julia> v +3-element Vector{Vector{Any}}: + [8675309] + [8675309] + [8675309] +``` + +To create an array of many independent inner arrays, use a [comprehension](@ref man-comprehension) instead. +This creates a new and distinct array on each iteration of the loop: + +```jldoctest +julia> v2 = [[] for _ in 1:3] +3-element Vector{Vector{Any}}: + [] + [] + [] + +julia> v2[1] === v2[2] === v2[3] +false + +julia> push!(v2[1], 8675309) +1-element Vector{Any}: + 8675309 + +julia> v2 +3-element Vector{Vector{Any}}: + [8675309] + [] + [] +``` See also: [`fill!`](@ref), [`zeros`](@ref), [`ones`](@ref), [`similar`](@ref). @@ -452,15 +512,15 @@ julia> fill(1.0, (2,3)) julia> fill(42) 0-dimensional Array{Int64, 0}: 42 -``` -If `x` is an object reference, all elements will refer to the same object: -```jldoctest -julia> A = fill(zeros(2), 2); +julia> A = fill(zeros(2), 2) # sets both elements to the same [0.0, 0.0] vector +2-element Vector{Vector{Float64}}: + [0.0, 0.0] + [0.0, 0.0] -julia> A[1][1] = 42; # modifies both A[1][1] and A[2][1] +julia> A[1][1] = 42; # modifies the filled value to be [42.0, 0.0] -julia> A +julia> A # both A[1] and A[2] are the very same vector 2-element Vector{Vector{Float64}}: [42.0, 0.0] [42.0, 0.0]