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

я функциональности `+`.

// Здесь мы объявим `Add` - типаж сложения, со вторым

// операндом типа `Bar`.

// Следующий блок реализует операцию: Foo + Bar = FooBar

impl ops::Add for Foo {

type Output = FooBar;

fn add(self, _rhs: Bar) -> FooBar {

println!("> Вызвали Foo.add(Bar)");

FooBar

}

}

// Если мы поменяем местами типы, то получим реализацию некоммутативного сложения.

// Здесь мы объявим `Add` - типаж сложения, со вторым

// операндом типа `Foo`.

// Этот блок реализует операцию: Bar + Foo = BarFoo

impl ops::Add for Bar {

type Output = BarFoo;

fn add(self, _rhs: Foo) -> BarFoo {

println!("> Вызвали Bar.add(Foo)");

BarFoo

}

}

fn main() {

println!("Foo + Bar = {:?}", Foo + Bar);

println!("Bar + Foo = {:?}", Bar + Foo);

}

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

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

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

Add, Syntax Index

Типаж Drop

Типаж Drop имеет только один метод: drop, который вызывается автоматически, когда объект выходит из области видимости. Основное применение типажа Drop заключается в том, чтобы освободить ресурсы, которыми владеет экземпляр реализации.

Box, Vec, String, File, и Process - это некоторые примеры типов, которые реализуют типаж Drop для освобождения ресурсов. Типаж Drop также может быть реализован вручную для любых индивидуальных типов данных.

В следующем примере мы добавим вывод в консоль к функции drop, чтобы было видно, когда она вызывается.

struct Droppable {

name: &'static str,

}

// Это простая реализация `drop`, которая добавляет вывод в консоль.

impl Drop for Droppable {

fn drop(&mut self) {

println!("> Сбросили {}", self.name);

}

}

fn main() {

let _a = Droppable { name: "a" };

// блок А

{

let _b = Droppable { name: "b" };

// блок Б

{

let _c = Droppable { name: "c" };

let _d = Droppable { name: "d" };

println!("Выходим из блока Б");

}

println!("Вышли из блока Б");

println!("Выходим из блока А");

}

println!("Вышли из блока А");

// Переменную можно сбросить вручную с помощью функции `drop`.

drop(_a);

// ЗАДАНИЕ ^ Попробуйте закомментировать эту строку

println!("Конец главной функции.");

// *Нельзя* сбросить `_a` снова, потому что переменная уже

// (вручную) сброшена.

}

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

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Итераторы

Типаж Iterator используется для итерирования по коллекциям, таким как массивы.

Типаж требует определить метод next, для получения следующего элемента. Данный метод в блоке impl может быть определён вручную или автоматически (как в массивах и диапазонах).

Для удобства использования, например в цикле for, некоторые коллекции превращаются в итераторы с помощью метода .into_iterator().

struct Fibonacci {

curr: u32,

next: u32,

}

// Реализация `Iterator` для `Fibonacci`.

// Для реализации типажа `Iterator` требуется реализовать метод `next`.

impl Iterator for Fibonacci {

type Item = u32;

// Здесь мы определяем последовательность, используя `.curr` и `.next`.

// Возвращаем тип `Option`:

//     * Когда в `Iterator` больше нет значений, будет возвращено `None`.

//     * В противном случае следующее значение оборачивается в `Some` и возвращается.

fn next(&mut self) -> Option {

let new_next = self.curr + self.next;

self.curr = self.next;

self.next = new_next;

// Поскольку последовательность Фибоначчи бесконечна,

// то `Iterator` никогда не вернет `None`, и всегда будет

// возвращаться `Some`.

Some(self.curr)

}

}

// Возвращается генератор последовательности Фибоначчи.

fn fibonacci() -> Fibonacci {

Fibonacci { curr: 0, next: 1 }

}

fn main() {

// `0..3` это `Iterator`, который генерирует : 0, 1, и 2.

let mut sequence = 0..3;

println!("Четыре подряд вызова `next`на 0..3");

println!("> {:?}", sequence.next());

println!("> {:?}", sequence.next());

println!("> {:?}", sequence.next());

println!("> {:?}", sequence.next());

// `for` работает через `Iterator` пока тот не вернет `None`.

// каждое значение `Some` распаковывается  и привязывается к переменной (здесь это `i`).

println!("Итерирование по 0..3 используя `for`");

for i in 0..3 {

println!("> {}", i);

}

// Метод `take(n)` уменьшает `Iterator` до его первых `n` членов.

println!("Первые четыре члена последовательности Фибоначчи: ");

for i in fibonacci().take(4) {

println!("> {}", i);

}

// Метод `skip(n)` сокращает `Iterator`, отбрасывая его первые `n` членов.

println!("Следующие четыре члена последовательности Фибоначчи: ");

for i in fibonacci().skip(4).take(4) {

println!("> {}", i);

}

let array = [1u32, 3, 3, 7];

// Метод `iter` превращает `Iterator` в массив/срез.