Rust doesn’t allow us to mark only certain fields as mutable. You can only mark whole struct as mutable or immutable.
For struct field you can use spread operator. But remember that data will be moved to new struct.
代码语言:javascript复制fn main() {
// --snip--
let user1 = User {
email: String::from("someone@example.com"),
username: String::from("someusername123"),
active: true,
sign_in_count: 1,
};
let user2 = User {
email: String::from("another@example.com"),
..user1
};
print!("{}", user1.email); // Works
print!("{}", user1.username); // Do not work, moved to user2 already
}
Tuple Structs
代码语言:javascript复制struct Color(i32, i32, i32);
struct Point(i32, i32, i32);
fn main() {
let black = Color(0, 0, 0);
let origin = Point(0, 0, 0);
}
Unit Structs
Structs with no fields
代码语言:javascript复制struct AlwaysEqual;
fn main() {
let subject = AlwaysEqual;
}
Struct as Function Parameter
代码语言:javascript复制struct Rectangle {
width: u32,
height: u32,
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!(
"The area of the rectangle is {} square pixels.",
area(&rect1)
);
}
fn area(rectangle: &Rectangle) -> u32 {
rectangle.width * rectangle.height
}
Print Debug Info for Struct
prints to stdout
代码语言:javascript复制#[derive(Debug)] // Required for print of struct
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!("rect1 is {:?}", rect1);
dbg!(&rect1);
}
prints to stderr
代码语言:javascript复制 let rect1 = Rectangle {
width: dbg!(30 * scale),
height: 50,
};
dbg!(&rect1); // use ref here to prevent ownership changes
Method
- Use
impl
to add method for a struct
#[derive(Debug)]
struct Rectangle {
width: u32,
height: u32,
}
impl Rectangle {
// define method for Rectangle
// the `&self` is shorthand for `self: &Self`
// the type Self is an alias for the type that the impl block is for.
fn area(&self) -> u32 {
self.width * self.height
}
}
fn main() {
let rect1 = Rectangle {
width: 30,
height: 50,
};
println!(
"The area of the rectangle is {} square pixels.",
rect1.area()
);
}
Calling method with Automatic Referencing and Dereferencing
In C and C , two different operators are used for calling methods: you use .
if you’re calling a method on the object directly and ->
if you’re calling the method on a pointer to the object and need to dereference the pointer first. In other words, if object
is a pointer, object->something()
is similar to (*object).something()
.
Rust automatically adds in &
, &mut
, or *
so object matches the signature of the method. In other words, the following are the same:
p1.distance(&p2);
(&p1).distance(&p2);
Constructor in methods
代码语言:javascript复制impl Rectangle {
fn square(size: u32) -> Self {
Self {
width: size,
height: size,
}
}
}
Rectangle::square(3);
Multiple impl
代码语言:javascript复制impl Rectangle {
fn area(&self) -> u32 {
self.width * self.height
}
}
impl Rectangle {
fn can_hold(&self, other: &Rectangle) -> bool {
self.width > other.width && self.height > other.height
}
}
// Caution: for method without ref on self, use `Rectangle::test()` instead
impl Rectangle {
fn test() {
print!("Test")
}
}