Пример использования 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;