Edit: I’ll update this from time to time
Summary
Introduction of =
for struct construction in Rust 2018.
let my_struct = MyStruct { a = 42 }; // New
let my_struct = MyStruct { a: 42 }; // Current
The new syntax is intended to gradually replace the current syntax. Existing code will continue to compile without warnings.
Motivation
Rust uses =
in assignment expressions. In contrast to this, when creating an instance of a struct, the :
instead of =
is used to initialize struct fields with values. This proposal aims to introduce a consistent notation for assignment related operations by introducing =
for struct field initialization.
As a consequence, this introduces a clear distinction in notation for assignment related operations and type annotations/definitions/ascriptions. Here are a few examples where :
is used to define the type:
// Struct definition
struct User {
username: String,
email: String,
}
// Trait bounds
fn print_area<T: HasArea>(shape: T) {
println!("This shape has an area of {}", shape.area());
}
Instead the use of =
introduces similarity to variable bindings:
let my_value = 42; // Assignment
let my_value: u64 = 42 // Assignment with type annotation
let my_struct = MyStruct { a = 42 }; // New struct construction syntax using `=`
This author believes that the improved consistency helps beginners. Furthermore, the notational difference between the definition and construction of structs is valuable to all users of Rust because with it, it becomes possible to tell them apart at a glance.
Guide-level explanation
Shipment strategy
Before Rust 2018 is shipped
- Introduce support for the
=
syntax - Continue support of
:
syntax without any warnings - Update to rustfix to make easy migration possible
- Update the documentation for Rust 2018 to use the new syntax
- Add a rule to clippy, disabled at first
After Rust 2018 has shipped
- Continue support of
:
syntax without any warnings - Enable clippy rule gradually (different clippy profiles)
Before next edition after Rust 2018
- New RFC that discusses the deprecation of the old syntax if this is desired
Destructuring and matching
Occurrences of :
are replaced with =
, the rest of the syntax remains unchanged:
struct MyStruct { x: i32 }
...
let my_struct = MyStruct { x: 42 }; // Current
let my_struct = MyStruct { x = 42 }; // New
// Destructuring: x_var = 42
let MyStruct { x: x_var } = my_struct; // Current
let MyStruct { x = x_var } = my_struct; // New
let x_var = my_struct.x // Without destructuring
// Matching
match Foo { x = 9 } {
// x
Foo { x } => {} // Current
Foo { x } => {} // New
// x_var
Foo { x: x_var} => {} // Current
Foo { x = x_var} => {} // New
// No var
Foo { x: 1..=10 } => {} // Current
Foo { x = 1..=10 } => {} // New
// x_var
Foo { x: x_var @ 1..=10} => {} // Current
Foo { x = x_var @ 1..=10 } => {} // New
}
Type ascriptions
This change makes struct construction fully compatible with type ascription in expressions (See RFC803)
let my_struct = MyStruct { a = 42: u64 };
Reference-level explanation
ToDo
Drawbacks
- Requires many documentation changes
- Different syntax than other languages: The current syntax mirrors the syntax used in JavaScript. The proposed change would make Rust’s syntax different. It is however similar to the syntax of C99 (explained further below)
- Struct definition and initialization now look different. Some people might consider this as a drawback. This author thinks that it is actually advantageous.
Rationale and alternatives
- Keep the current syntax, or
- Ship the
=
syntax with a different strategy than what is proposed here
Prior art
Similar syntax in C99
C (and therefore C++ as well) uses almost the same syntax to what is proposed here with the difference that a .
is placed in front of each field name.
struct point p = { .y = yvalue, .x = xvalue };
Previous RFC and discussions
- Previous RFC (RFC65) prior to Rust 1.0 for the same idea (not merged)
- Recent discussion (March 2018) in users forum
Unresolved questions
n/a