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

let elem = 5u8;

// Создадим пустой вектор (расширяемый массив).

let mut vec = Vec::new();

// В данном месте компилятор не знает точный тип `vec`, он лишь знает,

// что это вектор чего-то там (`Vec<_>`).

// Добавляем `elem` в вектор.

vec.push(elem);

// Ага! Теперь компилятор знает, что `vec` - это вектор, который хранит в себе тип `u8`

// (`Vec<u8>`)

// ЗАДАНИЕ ^ Попробуйте закомментировать строку `vec.push(elem)`

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

}

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

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Не потребовалось никакой аннотации типов переменных, компилятор счастлив, как и программист!

Оператор type используется, чтобы задать новое имя существующему типу. Имя типа должно быть в стиле UpperCamelCase, иначе компилятор выдаст предупреждение. Исключением являются примитивные типы: usize, f32 и другие.

// `NanoSecond` это новое имя для `u64`.

type NanoSecond = u64;

type Inch = u64;

// Используйте этот атрибут, чтобы не выводить предупреждение

// о именах не в стиле CamelCase

#[allow(non_camel_case_types)]

type u64_t = u64;

// ЗАДАНИЕ ^ Попробуйте удалить атрибут

fn main() {

// `NanoSecond` = `Inch` = `u64_t` = `u64`.

let nanoseconds: NanoSecond = 5 as u64_t;

let inches: Inch = 2 as u64_t;

// Обратите внимание, что псевдонимы *не предоставляют* никакой

// дополнительной безопасности типов, так как *не являются* новыми типами

println!("{} nanoseconds + {} inches = {} unit?",

nanoseconds,

inches,

nanoseconds + inches);

}

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

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Основное применение псевдонимов — сокращение размера кода: например, тип IoResult<T> является псевдонимом типа Result<T, IoError>.

Атрибуты

Примитивные типы могут быть сконвертированы в другие при помощи приведения типов.

Rust предоставляет преобразование между пользовательскими типами (такими как, struct и enum) через использование трейтов. Общие преобразования используют трейты From и Into. Однако есть и конкретные трейты для более частных случаев, например для конвертации String.

Типажи From и Into связаны по своей сути, и это стало частью их реализации. Если вы можете конвертировать тип А в тип В, то будет легко предположить, что мы должны быть в состоянии конвертировать тип В в тип А.

Типаж From позволяет типу определить, как он будет создаваться из другого типа, что предоставляет очень простой механизм конвертации между несколькими типами. Есть несколько реализаций этот типажа в стандартной библиотеке для преобразования примитивов и общих типов.

Для примера, мы можем легко конвертировать str в String

#![allow(unused)]

fn main() {

let my_str = "привет";

let my_string = String::from(my_str);

}

Мы можем сделать нечто похожее для определения конвертации для нашего собственного типа.

use std::convert::From;

#[derive(Debug)]

struct Number {

value: i32,

}

impl From<i32> for Number {

fn from(item: i32) -> Self {

Number { value: item }

}

}

fn main() {