Как инициализировать / построить глубоко вложенные структуры в Юлии? - PullRequest
2 голосов
/ 22 марта 2020

Я хочу создать более глубокие вложенные структуры. Похоже, пакета Setfield.jl достаточно для их заполнения. Но я борюсь с инициализацией (пустых) структур, чтобы заполнить их позже итеративно. Эти структуры выглядят так:

struct Bands
   B0::String
   B1::String
   B2::String
   B3::String
   B4::String
   B5::String
   .
   .
   .
   B25::String
end 


struct Masks
   mask1::Bands
   mask2::Bands
   mask3::Bands
   mask4::Bands
   mask5::Bands
   mask6::String
end

Я пробовал внутренние конструкторы и как описано здесь https://docs.julialang.org/en/v1/manual/constructors/#Incomplete -Initialization-1 . Кажется, что я должен установить все значения, как описано в https://jw3126.github.io/Setfield.jl/stable/intro/. Как я могу инициализировать вложенную структуру, в этом случае 131 значение сразу?

Ответы [ 2 ]

2 голосов
/ 22 марта 2020

Вы можете создавать конструкторы по умолчанию, которые просто помещают пустые объекты для всех полей, которые вы можете обновить позже, например

julia> struct Bands
           B0::String
           B1::String

           # Create a constructor that puts an empty String ("") for each field
           Bands() = new(("" for _ in 1:length(fieldnames(Bands)))...)

           # Define a vararg constructor
           Bands(args...) = new(args...)
       end

julia> struct Masks
           mask1::Bands
           mask2::Bands

           # Create a constructor that puts an empty Bands (Bands()) for each field
           Masks() = new((Bands() for _ in 1:length(fieldnames(Masks)))...)

           # Define a vararg constructor
           Masks(args...) = new(args...)
       end

julia> masks = Masks()
Masks(Bands("", ""), Bands("", ""))

julia> using Setfield

julia> masks = @set masks.mask1 = Bands("hello", "world") # Set a field of masks
Masks(Bands("hello", "world"), Bands("", ""))

julia> masks = @set masks.mask2.B0 = "hello" # Set a field of masks.mask2
Masks(Bands("hello", "world"), Bands("hello", ""))
1 голос
/ 23 марта 2020

Для вашего сценария использование Parameters.jl приведет к намного более чистому коду (кроме того, поскольку String является неизменным, ваш Bands struct должен быть изменяемым.

using Parameters

@with_kw mutable struct Bands
    B0::String = ""
    B1::String = ""
end

@with_kw struct Masks
    mask1::Bands = Bands()
    mask2::Bands = Bands()
end

Таким образом, ваш код чистый, читаемый, и вам не нужно определять огромное количество конструкторов.

...