Rust на примерах — страница 8 из 65

Пример использования enums для создания связанного списка:

use List::*;

enum List {

// Cons: Кортежная структура, которая хранит элемент

// и указатель на следующий узел

Cons(u32, Box),

// Nil: Узел, обозначающий конец связанного списка

Nil,

}

// Методы могут быть присоединены к перечислению

impl List {

// Создаём пустой список

fn new() -> List {

// `Nil` имеет тип `List`

Nil

}

// Функция, которая принимает список и возвращает тот же список,

// но с новым элементом в начале

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

// `Cons` также имеет тип `List`

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

}

// Возвращаем длину списка

fn len(&self) -> u32 {

// `self` должен быть сопоставлен (проверен на соответствие),

// поскольку поведение этого метода зависит от варианта `self`

// `self` имеет тип `&List`, а `*self` имеет тип `List`, сопоставление на

// конкретном типе `T` предпочтительнее, чем сопоставление по ссылке `&T`

match *self {

// Мы не можем завладеть `tail`, т.к. `self` заимствован;

// вместо этого возьмём ссылку на `tail`

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

// Базовый случай: Пустой список имеет нулевую длину

Nil => 0

}

}

// Возвращаем представление списка в виде (размещённой в куче) строки

fn stringify(&self) -> String {

match *self {

Cons(head, ref tail) => {

// `format!` похож на `print!`, но возвращает строку

// размещённую в куче, вместо вывода на консоль

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

},

Nil => {

format!("Nil")

},

}

}

}

fn main() {

// Создаём пустой связанный список

let mut list = List::new();

// Присоединяем несколько элементов

list = list.prepend(1);

list = list.prepend(2);

list = list.prepend(3);

// Отображаем окончательное состояние списка

println!("размер связанного списка: {}", list.len());

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

}

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

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Смотрите также:

Box и методы

Константы

В Rust есть два типа констант, которые могут быть объявлены в любой области видимости, включая глобальную. Оба требуют явной аннотации типа:

   • const: Неизменяемая переменная (в общем случае).

   • static: Возможно, изменяемая переменная с временем жизни 'static. Статическое время жизни выводится и не должно быть указано. Доступ или модификация изменяемой статической переменной небезопасно (см. unsafe).

// Константы объявлены в глобальной области видимости.

static LANGUAGE: &str = "Rust";

const THRESHOLD: i32 = 10;

fn is_big(n: i32) -> bool {

// Получаем доступ к константе внутри функции

n > THRESHOLD

}

fn main() {

let n = 16;

// Получаем доступ к константе внутри функции main

println!("Это язык {}", LANGUAGE);

println!("Установим предел, равный {}", THRESHOLD);

println!("Число {} {} предела", n, if is_big(n) { "больше" } else { "меньше" });

// Ошибка! `const` нельзя изменить.

THRESHOLD = 5;

// ИСПРАВЬТЕ ^ Закомментируйте эту строчку

}

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

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Смотрите также:

RFC дляconst/static, время жизни 'static

Связывание переменных

Rust предоставляет безопасность типов с помощью статической типизации. Тип переменной может быть указан при объявлении связи с переменной. Тем не менее, в большинстве случаев, компилятор сможет определить тип переменной из контекста.

Значения (как и литералы) могут быть привязаны к переменным, используя оператор let.

fn main() {

let an_integer = 1u32;

let a_boolean = true;

let unit = ();

// скопировать значение `an_integer` в `copied_integer`

let copied_integer = an_integer;

println!("Целое: {:?}", copied_integer);

println!("Логическое: {:?}", a_boolean);

println!("Встречайте единичное значение: {:?}", unit);

// Компилятор предупреждает о неиспользуемых переменных; эти предупреждения можно

// отключить используя подчёркивание перед именем переменной

let _unused_variable = 3u32;

let noisy_unused_variable = 2u32;

// ИСПРАВЬТЕ ^ Добавьте подчёркивание

}

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

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Изменяемость

По умолчанию связывание переменных является неизменяемым, но с помощью модификатора mut можно разрешить изменения.

fn main() {

let _immutable_binding = 1;

let mut mutable_binding = 1;