Best Way to Initialize this Struct

I would appreciate any opinions or thoughts on the following. I want to create a struct and I want one of the fields of the struct to be dependent on the others. Below is how I’ve accomplished this as a first pass.

struct MyStruct
    a::Int
    b::Real
    grid::Matrix{Float64}
end

function MyStruct(a::Int, b::Real)::MyStruct
    grid = zeros(Float64, a, a,)
    grid[1, 2:end-1] .= b
    grid[2:end-1, end] .= b
    return MyStruct(a, b, grid)
end

I’m wondering if this implementation is proper or if there is a better or more “julia” way of implementing it.

Edit: I should have made this clearer. I want the grid to be determined from a and b.

a seems to be redundant since you can infer it from the size of grid? But not a big deal.

However, I would define the struct as

struct MyStruct{T} 
    a::Int
    b::T
    grid::Matrix{T}
end

Or

struct MyStruct{B, T} 
    a::Int
    b::B
    grid::Matrix{T}
end

Since Real is not a concrete type and can make the struct slow if you pass it around often. Now the struct size is completely clear from the type signature and the derived types in the body.

2 Likes

To clarify: Do you want grid to take the values from b at initialization only or always?

At initialization only.

You may also be interested in Parameters.jl here, which enables keyword-based initialization as well as fields that depend on other fields (search for “Parameter interdependence” from the doc here)

ex.

julia> using Parameters

julia> @with_kw struct foo
        a::Int
        b::Real
        grid::Matrix{Float64} = g(a,b)
        end
foo

julia> function g(a,b)
           grid = zeros(Float64, a, a,)
           grid[1, 2:end-1] .= b
           grid[2:end-1, end] .= b
           grid
       end
g (generic function with 1 method)

julia> x = foo(a=4,b=1.2)
foo
  a: Int64 4
  b: Float64 1.2
  grid: Array{Float64}((4, 4)) [0.0 1.2 1.2 0.0; 0.0 0.0 0.0 1.2; 0.0 0.0 0.0 1.2; 0.0 0.0 0.0 0.0]


julia> x.grid
4×4 Matrix{Float64}:
 0.0  1.2  1.2  0.0
 0.0  0.0  0.0  1.2
 0.0  0.0  0.0  1.2
 0.0  0.0  0.0  0.0