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

The use declaration can be used so manual scoping isn't needed:

// An attribute to hide warnings for unused code.

#![allow(dead_code)]

enum Status {

Rich,

Poor,

}

enum Work {

Civilian,

Soldier,

}

fn main() {

// Explicitly `use` each name so they are available without

// manual scoping.

use crate::Status::{Poor, Rich};

// Automatically `use` each name inside `Work`.

use crate::Work::*;

// Equivalent to `Status::Poor`.

let status = Poor;

// Equivalent to `Work::Civilian`.

let work = Civilian;

match status {

// Note the lack of scoping because of the explicit `use` above.

Rich => println!("The rich have lots of money!"),

Poor => println!("The poor have no money..."),

}

match work {

// Note again the lack of scoping.

Civilian => println!("Civilians work!"),

Soldier  => println!("Soldiers fight!"),

}

}

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

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

See also:

match and use

C-like

enum can also be used as C-like enums.

// An attribute to hide warnings for unused code.

#![allow(dead_code)]

// enum with implicit discriminator (starts at 0)

enum Number {

Zero,

One,

Two,

}

// enum with explicit discriminator

enum Color {

Red = 0xff0000,

Green = 0x00ff00,

Blue = 0x0000ff,

}

fn main() {

// `enums` can be cast as integers.

println!("zero is {}", Number::Zero as i32);

println!("one is {}", Number::One as i32);

println!("roses are #{:06x}", Color::Red as i32);

println!("violets are #{:06x}", Color::Blue as i32);

}

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

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

See also:

casting

Testcase: linked-list

A common use for enums is to create a linked-list:

use crate::List::*;

enum List {

// Cons: Tuple struct that wraps an element and a pointer to the next node

Cons(u32, Box),

// Nil: A node that signifies the end of the linked list

Nil,

}

// Methods can be attached to an enum

impl List {

// Create an empty list

fn new() -> List {

// `Nil` has type `List`

Nil

}

// Consume a list, and return the same list with a new element at its front

fn prepend(self, elem: u32) -> List {

// `Cons` also has type List

Cons(elem, Box::new(self))

}

// Return the length of the list

fn len(&self) -> u32 {

// `self` has to be matched, because the behavior of this method

// depends on the variant of `self`

// `self` has type `&List`, and `*self` has type `List`, matching on a

// concrete type `T` is preferred over a match on a reference `&T`

match *self {

// Can't take ownership of the tail, because `self` is borrowed;

// instead take a reference to the tail

Cons(_, ref tail) => 1 + tail.len(),

// Base Case: An empty list has zero length

Nil => 0

}

}

// Return representation of the list as a (heap allocated) string

fn stringify(&self) -> String {

match *self {

Cons(head, ref tail) => {

// `format!` is similar to `print!`, but returns a heap

// allocated string instead of printing to the console

format!("{}, {}", head, tail.stringify())

},

Nil => {

format!("Nil")

},

}

}

}

fn main() {

// Create an empty linked list

let mut list = List::new();

// Prepend some elements

list = list.prepend(1);

list = list.prepend(2);

list = list.prepend(3);

// Show the final state of the list

println!("linked list has length: {}", list.len());

println!("{}", list.stringify());

}

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

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

See also:

Box and methods

constants

Rust has two different types of constants which can be declared in any scope including global. Both require explicit type annotation:

   • const: An unchangeable value (the common case).