Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to declare a struct where only some members can use a value from another struct?

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.

like image 891
ideasman42 Avatar asked Dec 12 '16 04:12

ideasman42


People also ask

What is a Go struct?

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.

How do you assign one structure to another structure in Golang?

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.

Can struct have methods?

A struct can contain properties, auto-implemented properties, methods, etc., same as classes. The following struct includes the static method.

What is AC struct?

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.


1 Answers

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.

like image 170
oli_obk Avatar answered Sep 21 '22 06:09

oli_obk