DynamicStructs is a Julia package that allows you to create structs with dynamic properties. These properties behave similarly to fields of type Any
in mutable structs, but are bound to the instance rather than the type, and can be added and deleted at runtime.
Install from the REPL with ]add DynamicStructs
.
julia> using DynamicStructs
julia> @dynamic struct Spaceship
name::String
end
julia> ship = Spaceship("Hail Mary", crew=["Grace", "Yao", "Ilyukhina"])
Spaceship("Hail Mary"; crew=["Grace", "Yao", "Ilyukhina"])
julia> ship.name, ship.crew
("Hail Mary", ["Grace", "Yao", "Ilyukhina"])
julia> ship.crew = ["Grace"]; # reassign crew
julia> ship.fuel = 20906.0; # assign fuel
julia> Spaceship("Hail Mary"; crew=["Grace"], fuel=20906.0)
julia> hasproperty(ship, :fuel)
true
julia> delete!(ship, :fuel) # delete fuel
Spaceship("Hail Mary"; crew=["Grace"])
julia> hasproperty(ship, :fuel)
false
- Create structs with both fields and dynamic properties using the
@dynamic
macro. - Use
mutable struct
to allow for modifying field values. - Type safety for fields.
- Add, modify, and delete dynamic properties at runtime.
- Check if types and instances are dynamic with
isdynamictype
andisdynamic
:
julia> (isdynamictype(Spaceship), isdynamic(ship), isdynamic(Spaceship))
(true, true, false)
NoFields
andOnlyFields
singleton types for methods ofBase.propertynames
:propertynames(x, NoFields())
returns only non-field property names.propertynames(x, OnlyFields())
returns only field names.
propertyvalues
takes the same arguments asBase.propertynames
and iterates over the names to return a tuple of values.propertypairs
returns the pairs, mapping the names ofBase.propertynames
to the values ofpropertyvalues
Inner constructors are not supported, as Julia's default constructors do useful conversions that would otherwise be overwritten. Moreover, a constructor that uses new
without passing a DynamicStructs.DynamicProperties
will not properly instantiate the dynamic instance.