Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default values for struct fields #1594

Closed
nrc opened this issue Apr 27, 2016 · 13 comments
Closed

Default values for struct fields #1594

nrc opened this issue Apr 27, 2016 · 13 comments
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.

Comments

@nrc
Copy link
Member

nrc commented Apr 27, 2016

strawman syntax:

struct Foo {
    a: String,
    b: i32 = 42,
}

To instantiate:

let f = Foo { a: "Hello".to_owned() };  // b gets default value of 42
let f = Foo { a: "Hello".to_owned(), .. };  // alternative syntax to make default use explicit
let f = Foo { a: "Hello".to_owned(), b: 51 };  // b is 'overridden'

cc https://internals.rust-lang.org/t/struct-field-defaults/3412

@nrc nrc added the T-lang Relevant to the language team, which will review and decide on the RFC. label Apr 27, 2016
@ticki
Copy link
Contributor

ticki commented Apr 27, 2016

I would much rather introduce .. as a sugar:

MyStruct {
    a: 2,
    .. // means:   .. Default::default()
}

@birkenfeld
Copy link

Would the default be an arbitrary expression, executed at Foo creation time, or a constant expression? The latter would make this a lot less useful than default().

@keeperofdakeys
Copy link

At the very least the syntax for using the default should be explicit (IE: using ..), otherwise this feature could become slightly confusing.

@ambrop72
Copy link

ambrop72 commented May 2, 2016

Hi, I think .. or similar should not be required to enable backward compatibility. Assume a library now has a struct with some fields, it would be possible to add another field with a default value without breaking client code that initializes only the old fields. Specifying default values in the struct declaration should be sufficient permission to omit them in the initialization.

@HeroesGrave
Copy link

There was a bit of discussion on this about a year ago here: https://www.reddit.com/r/rust/comments/2m99ly/idea_for_default_struct_fields/

Probably the most important thing about this proposal is that's it's providing more flexibility than just Default, as you can have default fields for a struct that isn't neccessarily default altogether.

@mark-i-m
Copy link
Member

It would be cool to provide both a const initializer (via default values) and a non-const one (via the Default). This is actually already possible via const functions, but it is a bit verbose IMHO. I think this would eliminate a lot of uses of lazy_static.

Example:

// In some library
pub struct Bar {
    ... // internals
}

// In my code
struct Foo {
    i: u64,
    b: Bar,
}

static f: Foo = Foo {
   i: 34,
   b: Default::default(), // Ooops! Cannot do this because `default` is non-const
};

In many cases, this leads to the use of a lazy_static, which may still be the right solution in a lot of cases. But the fact that we cannot use Default for static initializers is a bit unfortunate.

@kindlychung
Copy link

Also useful in a case like:

struct Point {
    pub x: f64,
    pub y: f64,
}

When later on you want to add a new field:

struct Point {
    pub x: f64,
    pub y: f64,
    norm: f64 = NAN,
}

impl Point {
   pub fn get_norm(&self) -> f64 {
        if(self.norm.is_nan()) {
            ...
        } else {
           self.norm
        }
   }
}

you don't have to change code across the whole project to add norm into every Point.

@ticki
Copy link
Contributor

ticki commented Sep 19, 2016

@kindlychung I think that mess with the goal of explicitness.

@sickHamm
Copy link

sickHamm commented Oct 9, 2016

Whether support private fields? I think like this code Foo { a: "Hello".to_owned(), .. } will be good way to initialize private fields.
Now, must do like this

Struct Foo {
          ...,
         pub __hide,
}
Foo { a: "Hello".to_owned(), ..Foo::default() };

@Centril
Copy link
Contributor

Centril commented Oct 7, 2018

Closing in favor of #1806 for tracking purposes.

@Centril Centril closed this as completed Oct 7, 2018
@utx0
Copy link

utx0 commented Jan 31, 2022

Hey what ended up happening to this? Would be super handle for the use case I have right now. Doesnt seam to have make it into code?

@nrc
Copy link
Member Author

nrc commented Jan 31, 2022

This RFC was closed in favour of 1806, which was closed as postponed, which means the lang team did not want to add the feature to the language at the time. I'm no longer on the lang team, but I believe this is not a current priority. It may be at some point.

@hkratz
Copy link

hkratz commented Jan 31, 2022

There is a new pre-RFC at IRLO.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the RFC.
Projects
None yet
Development

No branches or pull requests