Can I avoid field struct declaration?

I don’t know how to search this topic, then I prefer to ask.
If I did not misunderstood, the Constructor only works when all the field are supplied. I was wandering if I could define a struct and some of the fields will be generated by external functions (everything at once).
A minimal example:

mutable struct MyType
    N::Integer
    S::Symbol
    r::Array{Float64,2}

    if S == :sy1
        r = foo(N)
    elseif S == :sy2
        r = foo2(N)
    end

    foo(N) = rand(N,2)
    foo2(N) = rand(N,3)
end

a = MyType(10, :sy1) # do not declare r
display(a.r)

(The code above does not work, but has the main idea)

you need an inner constructor, or additional outer constructor if you want to leave option to initialize the r firld manually
https://docs.julialang.org/en/v1/manual/constructors/#Inner-Constructor-Methods-1

2 Likes

As always in Julia, you can just add methods to any function, also the constructor. It doesn’t have to be an inner constructor either:

mutable struct MyType
    N::Int
    S::Symbol
    r::Array{Float64,2}
end

function MyType(N, S)
    if S == :sy1
        return MyType(N, S, rand(N, 2))
    elseif S == :sy2
        return MyType(N, S, rand(N, 3))
    else
        error("Wrong input.")
    end
end

a = MyType(4, :sy2)

display(a.r)
4×3 Array{Float64,2}:
 0.310291  0.371418   0.751672  
 0.72183   0.932101   0.00485553
 0.58432   0.0196664  0.74358   
 0.762198  0.925545   0.776586

BTW, I changed the type of the N parameter from Integer to Int, since Integer is an abstract type, which normally leads to poor performance in structs. If you want to allow all sorts of integer types, you should make a parametric type.

Thank you DNF.
Indeed your code does what I want, but my wandering was if I could do everything at once, during the struct definition - I don’t know if this is a good idea, but I just want to know the possibility.

Does it really matter? Can’t you consider the constructor to be part of the definition?

For default values you can use a macro, from here https://github.com/mauro3/Parameters.jl/blob/master/README.md

Not sure if you can accomplish exactly what you want, though.

Does not really matter :upside_down_face:
As I sad, just a curiosity