Would named tuples work for you?
julia> ab = (a=zeros(2, 2), b=zeros(2, 2))
(a = [0.0 0.0; 0.0 0.0], b = [0.0 0.0; 0.0 0.0])
julia> cd = (c=zeros(2, 2), d=zeros(1, 1))
(c = [0.0 0.0; 0.0 0.0], d = [0.0;;])
julia> abcd = (; ab..., cd...)
(a = [0.0 0.0; 0.0 0.0], b = [0.0 0.0; 0.0 0.0], c = [0.0 0.0; 0.0 0.0], d = [0.0;;])
Here, the splatting allocates a new tuple, but does not allocate the arrays inside the fields
julia> ab.a[1, 2] = 1
1
julia> abcd
(a = [0.0 1.0; 0.0 0.0], b = [0.0 0.0; 0.0 0.0], c = [0.0 0.0; 0.0 0.0], d = [0.0;;])
and can be easily passed to your struct as well:
julia> mystruct(; ab...)
mystruct
a: Array{Float64}((2, 2)) [0.0 1.0; 0.0 0.0]
b: Array{Float64}((2, 2)) [0.0 0.0; 0.0 0.0]
c: Nothing nothing
d: Nothing nothing