I’m trying to create a vector as, that contains the value of field a for each struct Foo in the vector of structs foo without losing reference so that changing the values of as would also affect the values of foo. Here is a simple example:
julia> mutable struct Foo{N<:Number}
a::N
b::N
end
julia> foo = [Foo(1, 1), Foo(2, 2)]
2-element Vector{Foo{Int64}}:
Foo{Int64}(1, 1)
Foo{Int64}(2, 2)
julia> as = [f.a for f in foo]
2-element Vector{Int64}:
1
2
julia> as[1] = 3
3
julia> foo[1]
Foo{Int64}(1, 1) ## my target here is to have Foo{Int64}(3, 1) as result instead
@jling is right — doing exactly what you ask for is impossible so long as the struct fields are immutable. But what you ask for is the default behavior for mutable fields (such as arrays or a number in a Ref), in which case the struct itself need not be mutable.
I just wanted to add, maybe you will find StructArrays.jl useful. It lets you deal with arrays-of-structs, while internally being a struct-of-arrays. Used in conjunction with Accessors.jl, this can be pretty handy. See this answer.
thanks a lot for suggesting StructArrays. Any ideas how to customise StructArray in case of nested structs?, something like following:
using StructArrays
julia> struct SubFoo{N<:Number}
x::N
y::N
z::N
end
julia> struct Foo{N<:Number}
a::SubFoo{N}
b::N
end
julia> foo = [Foo(SubFoo(1, 2, 3), 1), Foo(SubFoo(1, 2, 3), 2)] |> StructArray
2-element StructArray(::Vector{SubFoo{Int64}}, ::Vector{Int64}) with eltype Foo{Int64}:
Foo{Int64}(SubFoo{Int64}(1, 2, 3), 1)
Foo{Int64}(SubFoo{Int64}(1, 2, 3), 2)
julia> foo.a.x ## not possible, would be nice to get [1, 1] as a result
thanks, the first solution works perfectly for me. I’ve just gone with T <: SubFoo instead of fieldcount(T) > 0, as fieldcount wouldn’t work with abstract types or Unions.