Rust by Example — страница 14 из 66

2 | 3 | 5 | 7 | 11 => println!("This is a prime"),

// TODO ^ Try adding 13 to the list of prime values

// Match an inclusive range

13..=19 => println!("A teen"),

// Handle the rest of cases

_ => println!("Ain't special"),

// TODO ^ Try commenting out this catch-all arm

}

let boolean = true;

// Match is an expression too

let binary = match boolean {

// The arms of a match must cover all the possible values

false => 0,

true => 1,

// TODO ^ Try commenting out one of these arms

};

println!("{} -> {}", boolean, binary);

}

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

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Destructuring

A match block can destructure items in a variety of ways.

   • Destructuring Tuples

   • Destructuring Enums

   • Destructuring Pointers

   • Destructuring Structures

tuples

Tuples can be destructured in a match as follows:

fn main() {

let triple = (0, -2, 3);

// TODO ^ Try different values for `triple`

println!("Tell me about {:?}", triple);

// Match can be used to destructure a tuple

match triple {

// Destructure the second and third elements

(0, y, z) => println!("First is `0`, `y` is {:?}, and `z` is {:?}", y, z),

(1, ..)  => println!("First is `1` and the rest doesn't matter"),

// `..` can be the used ignore the rest of the tuple

_      => println!("It doesn't matter what they are"),

// `_` means don't bind the value to a variable

}

}

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

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

See also:

Tuples

enums

An enum is destructured similarly:

// `allow` required to silence warnings because only

// one variant is used.

#[allow(dead_code)]

enum Color {

// These 3 are specified solely by their name.

Red,

Blue,

Green,

// These likewise tie `u32` tuples to different names: color models.

RGB(u32, u32, u32),

HSV(u32, u32, u32),

HSL(u32, u32, u32),

CMY(u32, u32, u32),

CMYK(u32, u32, u32, u32),

}

fn main() {

let color = Color::RGB(122, 17, 40);

// TODO ^ Try different variants for `color`

println!("What color is it?");

// An `enum` can be destructured using a `match`.

match color {

Color::Red   => println!("The color is Red!"),

Color::Blue  => println!("The color is Blue!"),

Color::Green => println!("The color is Green!"),

Color::RGB(r, g, b) =>

println!("Red: {}, green: {}, and blue: {}!", r, g, b),

Color::HSV(h, s, v) =>

println!("Hue: {}, saturation: {}, value: {}!", h, s, v),

Color::HSL(h, s, l) =>

println!("Hue: {}, saturation: {}, lightness: {}!", h, s, l),

Color::CMY(c, m, y) =>

println!("Cyan: {}, magenta: {}, yellow: {}!", c, m, y),

Color::CMYK(c, m, y, k) =>

println!("Cyan: {}, magenta: {}, yellow: {}, key (black): {}!",

c, m, y, k),

// Don't need another arm because all variants have been examined

}

}

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

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

See also:

#[allow(...)], color models and enum

pointers/ref

For pointers, a distinction needs to be made between destructuring and dereferencing as they are different concepts which are used differently from a language like C.

   • Dereferencing uses *

   • Destructuring uses &, ref, and ref mut

fn main() {

// Assign a reference of type `i32`. The `&` signifies there

// is a reference being assigned.

let reference = &4;

match reference {

// If `reference` is pattern matched against `&val`, it results

// in a comparison like:

// `&i32`

// `&val`

// ^ We see that if the matching `&`s are dropped, then the `i32`

// should be assigned to `val`.

&val => println!("Got a value via destructuring: {:?}", val),

}

// To avoid the `&`, you dereference before matching.

match *reference {

val => println!("Got a value via dereferencing: {:?}", val),

}

// What if you don't start with a reference? `reference` was a `&`

// because the right side was already a reference. This is not

// a reference because the right side is not one.

let _not_a_reference = 3;

// Rust provides `ref` for exactly this purpose. It modifies the

// assignment so that a reference is created for the element; this

// reference is assigned.

let ref _is_a_reference = 3;

// Accordingly, by defining 2 values without references, references

// can be retrieved via `ref` and `ref mut`.