Setting individual fields for struct in array


#1

Could anyone suggest how to make the following:

struct A b::Int; c::Int end
as = [A(1, 1), A(2, 2)]
as[2].c = 3

work without resorting to:

  • mutable types
  • recreating A with a changed field

Ideally the produced llvm code might be similar to C equivalent (*pointer).c = 3, so the solution may involve Ref, unsafe methods etc. I checked the documentation, and some GitHub threads, but still can’t figure out how to do this and bypass Julia’s convention for immutability in this particular case.


#2

I would recommend the following procedure to you:

struct A{T <: Integer} 
b::Vector{T}
c::Vector{T}
A(b::T, c::T) where T = new{T}([b], [c])
end


as = [A(1, 1); A(2, 2)]
as[2].c[1] = 3

Maybe it’s even possible to implement a specialized value to array conversion such that you do not have to use indexing in the last expression…


#3

See these issues that give deep insights of what’s going on about this:
https://github.com/JuliaLang/julia/pull/21912
https://github.com/JuliaLang/julia/issues/17115


#4

In the meantime, you could try something like this

struct A{T<:Integer}
    b::Base.RefValue{T}
    c::Base.RefValue{T}
end
A(b::T, c::T) where {T<:Integer} = A{T}(Ref(b), Ref(c))

Base.show(io::IO, a::A) = print(io, "A(", a.b[], ", ", a.c[], ")")

as = [A(1, 1); A(2, 2)]
as[2].c[] = 3

#5

Also, see this previous post Mutable field in immutable type and this comment on Immutable vs Type: reassignment via arrays and performance.


#6

Thank you @cdsousa, but some code snippets which I encountered in these threads will be available in 1.0+, as I understood. At least methods mentioned are not available in 0.6. It is just very strange that there is no way to do something similar, even with some low-level code, in the current version. But I suspect that I’m missing something, if you would be able to provide a short snippet of working code, I would be grateful.


#7

@pabloferz Is it possible to not uglify the struct definition, and obtain these RefValues in some other way?


#8

@jonas-kr your solution introduces mutable objects (Vector), this makes the whole point of using immutable structs in array irrelevant.