Rust has a useful feature where you can use an existing struct and only override some of its members. For example, a value of the following struct
struct SomeTool {
pub unique_id: String,
pub poll: Option<fn(&Context) -> bool>,
pub exec: Option<fn(&mut Context) -> ToolResult>,
pub modal: Option<fn(&mut Context) -> ToolResult>,
pub ui: Option<fn(&mut UIPanel)>,
}
can be initialized by passing in a struct instance (e.g. SomeTool::default()
):
new_tool = SomeTool {
unique_id: "tool.foobar".to_string(),
exec: Some(foobar_exec)
.. SomeTool::default()
};
I want to be able to declare SomeTool
without having to explicitly list every callback (adding new callbacks in the future may lead to many additions of None
all over a codebase).
This works well, but now I could accidentally leave out unique_id
for some other initialization, and it would use whatever is in the default
.
Is there a way to describe a struct that can have some members overridden but not others?
Note that the real world use-case has more members than this (making the chance of accidents higher), just simplified for the question.
In Go programming, a structure or struct is a user-defined type to store a collection of different fields into a single field. For example, suppose you have a player and want to store his name and age. You can create two variables, name, and age, to store the values.
A struct variable in Golang can be copied to another variable easily using the assignment statement(=). Any changes made to the second struct will not be reflected back to the first struct.
A struct can contain properties, auto-implemented properties, methods, etc., same as classes. The following struct includes the static method.
C struct, short for C Structure, is an user-defined data type available in C. It allows a user to combine data items of possibly different data types under a single name. C structs are different from arrays because arrays hold data of similar data-types only.
Since your unique_id
is supposed to be unique, it should not have a Default
constructor. But if you remove the Default
impl from a hypothetical UniqueId
type, then you won't be able to derive Default
for SomeTool
.
The currently working solution is to move all fields that don't require a value to a sub-struct and not implement Default
for SomeTool
. Thus you'd be able to use SomeTool
as follows:
new_tool = SomeTool {
unique_id: "tool.foobar".to_string(),
callbacks: Callbacks {
exec: Some(foobar_exec),
.. Callbacks::default()
}
};
There is a hypothetical feature that Rust might get in the future, which allows you to have two structs with the same fields to be the base expression in a struct expression. That feature would allow you to use the sub-struct to initialize all the fields that the sub-struct and SomeTool
have in common, but not more.
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