Выбрать главу

   • Tuple structs, which are, basically, named tuples.

   • The classic C structs

   • Unit structs, which are field-less, are useful for generics.

#[derive(Debug)]

struct Person {

name: String,

age: u8,

}

// A unit struct

struct Unit;

// A tuple struct

struct Pair(i32, f32);

// A struct with two fields

struct Point {

x: f32,

y: f32,

}

// Structs can be reused as fields of another struct

#[allow(dead_code)]

struct Rectangle {

// A rectangle can be specified by where the top left and bottom right

// corners are in space.

top_left: Point,

bottom_right: Point,

}

fn main() {

// Create struct with field init shorthand

let name = String::from("Peter");

let age = 27;

let peter = Person { name, age };

// Print debug struct

println!("{:?}", peter);

// Instantiate a `Point`

let point: Point = Point { x: 10.3, y: 0.4 };

// Access the fields of the point

println!("point coordinates: ({}, {})", point.x, point.y);

// Make a new point by using struct update syntax to use the fields of our

// other one

let bottom_right = Point { x: 5.2, ..point };

// `bottom_right.y` will be the same as `point.y` because we used that field

// from `point`

println!("second point: ({}, {})", bottom_right.x, bottom_right.y);

// Destructure the point using a `let` binding

let Point { x: top_edge, y: left_edge } = point;

let _rectangle = Rectangle {

// struct instantiation is an expression too

top_left: Point { x: left_edge, y: top_edge },

bottom_right: bottom_right,

};

// Instantiate a unit struct

let _unit = Unit;

// Instantiate a tuple struct

let pair = Pair(1, 0.1);

// Access the fields of a tuple struct

println!("pair contains {:?} and {:?}", pair.0, pair.1);

// Destructure a tuple struct

let Pair(integer, decimal) = pair;

println!("pair contains {:?} and {:?}", integer, decimal);

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

   1. Add a function rect_area which calculates the area of a rectangle (try using nested destructuring).

   2. Add a function square which takes a Point and a f32 as arguments, and returns a Rectangle with its lower left corner on the point, and a width and height corresponding to the f32.

attributes, and destructuring

The enum keyword allows the creation of a type which may be one of a few different variants. Any variant which is valid as a struct is also valid as an enum.

// Create an `enum` to classify a web event. Note how both

// names and type information together specify the variant:

// `PageLoad != PageUnload` and `KeyPress(char) != Paste(String)`.

// Each is different and independent.

enum WebEvent {

// An `enum` may either be `unit-like`,

PageLoad,

PageUnload,

// like tuple structs,

KeyPress(char),

Paste(String),

// or c-like structures.

Click { x: i64, y: i64 },

}

// A function which takes a `WebEvent` enum as an argument and

// returns nothing.

fn inspect(event: WebEvent) {

match event {

WebEvent::PageLoad => println!("page loaded"),

WebEvent::PageUnload => println!("page unloaded"),

// Destructure `c` from inside the `enum`.

WebEvent::KeyPress(c) => println!("pressed '{}'.", c),

WebEvent::Paste(s) => println!("pasted \"{}\".", s),

// Destructure `Click` into `x` and `y`.

WebEvent::Click { x, y } => {

println!("clicked at x={}, y={}.", x, y);

},

}

}

fn main() {

let pressed = WebEvent::KeyPress('x');

// `to_owned()` creates an owned `String` from a string slice.

let pasted = WebEvent::Paste("my text".to_owned());

let click = WebEvent::Click { x: 20, y: 80 };

let load = WebEvent::PageLoad;

let unload = WebEvent::PageUnload;

inspect(pressed);

inspect(pasted);

inspect(click);

inspect(load);

inspect(unload);

}

הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

If you use a type alias, you can refer to each enum variant via its alias. This might be useful if the enum's name is too long or too generic, and you want to rename it.