Is there any way to add a field to an already defined struct? I have a case where I have no idea of how many fields I will need, so I would like to be able to do something similar to Matlab’s structs i.e:
MatlabStruct.NewField = "SomeValue"
Which will not work in Julia if “NewField” is not already defined in the struct. I would like to be able to do this some way since I prefer struct syntax much more than “Dicts” due to the “.” syntax instead of [“”], which gets quite cumbersome quickly (in my own opinion).
If it is possible to do what I want, I would like to know - if it is still not possible that is of course also an answer.
It’s not possible to dynamically add fields to a struct in Julia for a variety of mostly performance related reasons. However, if it’s only a question of syntax, dot overloading is available like this:
Which seems to do what I actually want, even though it might not be best practice as you mention. Using a dict with the syntax you propose also seem like a good option, but that would mean I need to implement the Base get/set property for every custom Dict I define I suppose?
Now I am a bit closer to my goal none the less so thank you very much!
Doesn’t the VarStructs.jl package basically use the same idea as @GunnarFarneback? That is, it uses a Dict to map field names to field properties? Thank you.
I just looked at the package and yes, it uses the same idea. It does add a couple of bells and whistles around it, most importantly a macro to create such structs and support for handling unset values and enforce types of the values. It also adds a bit of illusion that it actually creates a struct with the given fields rather than a wrapped Dict, but that won’t convince type inference. As long as you don’t expect more than it actually provides it should be fine to use it.
I will be using it mainly for a tool which allows a user to make basically a text document, so it should be fine, thanks! Especially since top performance is not a priority in the first write of the code, trying to go for convenience this time.
Could you explain the point with type inference with a bit more detail? Basically my understanding from your reply is that even though it appears as struct to me when working with it, the Julia compiler might not regard it as such and not be able to optimize it? I like to learn.
This is a common question (one that I asked before also). There are a few ways to change structs when prototyping. Solutions range from Named Tuples (like above) to something like the following:
struct Foo1()
# fieldnames
end
const Foo = Foo1
and then when you want to change the fields
struct Foo2()
# add new fields
end
const Foo = Foo2() # rebind
Thanks for your input! Nice to know these packages exist.
In my case it was not about prototyping, but making the data structure actually behave like a structure and being able to add fields at will. Here VarStructs.jl has proven quite useful.
The only thing which annoys me using VarStructs is that the auto-completion (i.e. TAB in REPL) does not show all the fields connected to the struct anymore. Wondering if there is any way to change that?
This is because VarStructs.jl does not implement Base.propertynames() for the defined structures. If you add an implementation for this function as well, as @GunnarFarneback suggested, the Julia REPL will pick that up and autocomplete your field names. HTH!
That being said, you could just use a Dict with Symbol keys instead of tweaking structs for something which they were not really designed. In other words, do not add all that boilerplate to hide the behavior behind a struct-like interface, simply use the Dict API directly instead. All the more since this will make reading your code easier for others, who will probably not expect structs with dynamic fields.