-
Notifications
You must be signed in to change notification settings - Fork 1.5k
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
derive(new) #1318
Comments
The Overall I'm really skeptical about this one, sorry. Big 👎 |
It wouldn't work with enums (well, a pattern I see some times is having a constructor for each variant with the snake case name of each variant taking the same fields. I don't think this is common enough to be worthwhile). The reason to use this pattern (and I use it a lot and see others using it a lot in the compiler) is that it makes instantiating the struct much nicer:
vs.
Sure there's a trade-off with brittle field order, but in many cases it is worth it. Default only works if you can have a ctor which takes no arguments, not if you want to take one for each field. As you say, the implementation of this is trivial - it is pure boiler plate, which makes it an excellent candidate for automation. |
enum example:
gives
I expect this use to be much less common. |
I think we should separate two concerns:
|
There’s nothing It is common, though. Just search through the standard library for I also 👎 here for time being. While I found myself creating private structs with boiler-platey |
Whilst this isn't the biggest change in the world, and it has some benefit (less boiler plate) for pretty much zero-cost - if you never use the feature there is no cost to you and it can't affect the language in any surprising way. |
I'd be way more interested in seeing a solution that involves making |
@nixpulvis, this is already possible through the compiler plugin API. |
I don't find the pattern of
This argument could be made for pretty much any change. Personally, I think it does have a cost given the argument order sensitivity, in that it could lead a lot of crates to accidentally break API. It's just a bit too sensitive. I think a better idea would be
Which would generate:
That is, it implements a constructor on the fields specified, in the order specified, provided all non-specified fields implement |
I started a custom derive implementation at https://github.com/nrc/derive-new. WIP but works for basic braced structs at least. |
This is a simple idea, easy to understand and to remember, and it shortens the code in basic situations. |
With "Macros 1.1" it is possible to make a library implement this, and very soon run it on stable Rust. Does this need to be in the language or standard library? |
Not in the language, but it's simple and basic enough to be a macro in the std library/prelude. |
Derived
|
The constructor pattern is well-used in Rust, but is very boiler-platey. I propose allowing
#[derive(new)]
to be added to structs to provide the common constructor pattern.When placed on a struct called
Foo
with fieldsf_0
tof_n
with typesT_0
toT_n
it would create an inherent impl for that struct with a single function callednew
which would taken
args, with typesT_0
toT_n
and return aFoo
, it would simply create a newFoo
object mapping args to fields. It would bepub
ifFoo
waspub
. The impl would have the same type and lifetime parameters as the struct.This is a bit different from existing
derive
functionallity, since it takes a function name rather than a trait name as input and creates an inherent impl, rather than a trait impl. But it would work in basically the same way and have all the same benefits.The text was updated successfully, but these errors were encountered: