Бесплатная библиотека
Читайте книгу на сайте или телефоне
Rust на примерах - Читать Любимую Русскую Полную Книгу 👉 Read-E-Book.com

Rust на примерах

Электронная книга - «Rust на примерах». Краткое содержание книги:

https://doc.rust-lang.ru/stable/rust-by-example/
1 ... 23 24 25 26 27 28 29 30 31 ... 92
Перейти на страницу:

}

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

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

Использование move перед вертикальными линиями позволяет получить владение над захваченными переменными:

fn main() {

// Vec` не поддерживает копирование.

let haystack = vec![1, 2, 3];

let contains = move |needle| haystack.contains(needle);

println!("{}", contains(&1));

println!("{}", contains(&4));

// println!("Количество элементов {} в векторе", haystack.len());

// ^ Уберите комментарий с этой строки и в результате получите ошибку компиляции,

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

// переменную после передачи владения.

// Удалите `move` у замыкания и _haystack_ будет заимствован по неизменяемой

// ссылке, и удалённый комментарий теперь не вызывает ошибки.

}

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

XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

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

Box и std::mem::drop

Как входные параметры

В то время как замыкания Rust выбирают способ захвата переменных на лету, по большей части без указания типов, эта двусмысленность недопустима при написании функций. При использовании замыкания в качестве входного параметра, его тип должен быть указан с использованием одного из типажей. Вот они, в порядке уменьшения ограничений:

   • Fn: замыкание захватывает по ссылке (&T)

   • FnMut: замыкание захватывает по изменяемой ссылке (&mut T)

   • FnOnce: замыкание захватывает по значению (T)

Компилятор стремится захватывать переменные наименее ограничивающим способом.

Для примера, рассмотрим аргумент, указанный как FnOnce. Это означает, что замыкание может захватывать &T, &mut T, или T, но компилятор в итоге будет выбирать в зависимости от того, как захваченные переменные используются в замыкании.

Это связано с тем, что если перемещение возможно, тогда любой тип заимствования также должен быть возможен. Отметим, что обратное не верно. Если параметр указан как Fn, то захват переменных как &mut T или T недопустим.

В следующем примере попробуйте поменять местами использование Fn, FnMut, и FnOnce, чтобы увидеть результат:

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

// <F> обозначает, что F - "параметр общего типа"

fn apply<F>(f: F) where

// Замыкание ничего не принимает и не возвращает.

F: FnOnce() {

// ^ TODO: Попробуйте изменить это на `Fn` или `FnMut`.

f();

}

// Функция, которая принимает замыкание и возвращает `i32`.

fn apply_to_3<F>(f: F) -> i32 where

// Замыкание принимает `i32` и возвращает `i32`.

F: Fn(i32) -> i32 {

f(3)

}

fn main() {

use std::mem;

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

// Не копируемый тип.

// `to_owned` преобразует заимствованные данные в собственные.

let mut farewell = "пока".to_owned();

// Захват двух переменных: `greeting` по ссылке и

// `farewell` по значению.

let diary = || {

// `greeting` захватывается по ссылке: требует `Fn`.

println!("Я сказал {}.", greeting);

// Изменяемость требует от `farewell` быть захваченным

// по изменяемой ссылке. Сейчас требуется `FnMut`.

farewell.push_str("!!!");

println!("Потом я закричал {}.", farewell);

println!("Теперь я могу поспать. zzzzz");

// Ручной вызов удаления требуется от `farewell`

// быть захваченным по значению. Теперь требуется `FnOnce`.

mem::drop(farewell);

};

// Вызов функции, которая выполняет замыкание.

1 ... 23 24 25 26 27 28 29 30 31 ... 92
Перейти на страницу:
0
Сюжет
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
0
Атмосфера
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
0
Главный герой
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
0
Общее впечатление
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
Итоговая оценка: 0.0 из 10 (голосов: 0 / История оценок)