Is there a way to add default parameters for mutable structs in Julia?
I'm trying to write something like the following:
mutable struct Scale
# Set default values that will be changed by fit!()
domain_min::Float64 = 0.0
domain_max::Float64 = 1.0
range_min::Float64 = 0.0
range_max::Float64 = 1.0
end
function fit!(data::Array)
# Set struct params here using `data`
end
Is there a way to do this or should I try a different approach?
Type parameters may be omitted when they do not need to be referenced or restricted. Julia's type system is designed to be powerful and expressive, yet clear, intuitive and unobtrusive. Many Julia programmers may never feel the need to write code that explicitly uses types.
I noticed that when a struct is declared, its fields are immutable by default unless the mutable keyword is used. What is the reason for this? Is it good practice to use mutable structs?
Writing mutable struct Foo makes you ask "does this really need to be mutable?", which is a good thing! Immutable struct types are the closest thing we have to value type structs in other languages. We inline them in arrays in at least some cases, and being immutable makes it much harder to tell whether they are value or reference types.
In Julia, type objects also serve as constructor functions: they create new instances of themselves when applied to an argument tuple as a function. This much was already mentioned briefly when composite types were introduced.
This is exactly what Base.@kwdef
does:
julia> Base.@kwdef mutable struct Scale
# Set default values that will be changed by fit!()
domain_min::Float64 = 0.0
domain_max::Float64 = 1.0
range_min::Float64 = 0.0
range_max::Float64 = 1.0
end
Scale
# All parameters to their default values
julia> Scale()
Scale(0.0, 1.0, 0.0, 1.0)
# Specify some parameter(s) using keyword argument(s)
julia> Scale(range_min = 0.5)
Scale(0.0, 1.0, 0.5, 1.0)
I prefer using Parameters.jl
because it provides also a nicer way the struct
s are displayed which is much nicer for debugging:
julia> using Parameters
julia> @with_kw struct A
a::Int=5
b::String="hello"
c::Float64
end;
julia> A(c=3.5)
A
a: Int64 5
b: String "hello"
c: Float64 3.5
Or you can also just go the long way and define it yourself with constructors, as you would normally do if you want to instantiate it in several possible ways.
mutable struct Scale
# Set default values that will be changed by fit!()
domain_min::Float64
domain_max::Float64
range_min::Float64
range_max::Float64
end
# With default values, but no keywords
julia> Scale(dmin=1.,dmax=2.,rmin=1.,rmax=2.) = Scale(dmin, dmax, rmin, rmax)
Scale
julia> Scale(3.,4.)
Scale(3.0, 4.0, 1.0, 2.0)
# With keyword arguments:
julia> Scale(;dmin=1.,dmax=2.,rmin=1.,rmax=2.) = Scale(dmin, dmax, rmin, rmax)
Scale
julia> Scale(rmax=3., rmin=1.2)
Scale(1.0, 2.0, 1.2, 3.0)
Notice the difference between the two constructors, one has a semicolon ;
the other not. I would not recommend using both constructors at the same time, this may lead to some confusion.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With