РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
571 of 1245 menu

Трейт FnMut

Трейт FnMut - это один из трёх трейтов для вызываемых объектов в Rust, наряду с Fn и FnOnce. Он описывает функции и замыкания, которые могут быть вызваны несколько раз и при этом изменяют захваченные переменные окружения. В отличие от трейта Fn, который допускает только неизменяемый доступ к захваченному состоянию, FnMut позволяет изменять это состояние. Параметром трейт принимает набор типов аргументов и возвращаемый тип через ассоциированный тип Output.

Замыкания автоматически реализуют FnMut, если они изменяют захваченные переменные. Любой тип, реализующий FnMut, также реализует FnOnce, но не обязательно реализует Fn.

Синтаксис

trait FnMut<Args>: FnOnce<Args> { extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output; }

На практике напрямую трейт FnMut почти никогда не реализуют вручную - компилятор генерирует реализацию автоматически для замыканий. В сигнатурах функций трейт используют как ограничение вида F: FnMut(A) -> B или impl FnMut(A) -> B.

Пример

Давайте создадим замыкание, которое изменяет захваченную переменную counter, и вызовем его несколько раз:

fn main() { let mut counter = 0; let mut increment = || { counter += 1; println!("{}", counter); }; increment(); increment(); increment(); }

Результат выполнения кода:

1 2 3

Пример

Давайте напишем функцию, которая принимает замыкание с ограничением FnMut и применяет его к каждому элементу вектора:

fn apply_all<F>(items: &mut Vec<i32>, mut f: F) where F: FnMut(i32) -> i32, { for item in items.iter_mut() { *item = f(*item); } } fn main() { let mut numbers = vec![1, 2, 3, 4, 5]; let mut factor = 1; apply_all(&mut numbers, |x| { factor += 1; x * factor }); println!("{:?}", numbers); }

Результат выполнения кода:

[2, 6, 12, 20, 30]

Замыкание изменяет переменную factor при каждом вызове, поэтому каждый элемент умножается на своё уникальное значение.

Пример

Давайте сохраним замыкание в переменной с типом Box<dyn FnMut()> и вызовем его через этот трейт-объект:

fn main() { let mut total = 0; let mut acc: Box<dyn FnMut(i32)> = Box::new(|x| { total += x; println!("total = {}", total); }); acc(10); acc(20); acc(30); }

Результат выполнения кода:

total = 10 total = 30 total = 60

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

  • трейт Fn,
    который описывает замыкания без изменения захваченного состояния
  • трейт FnOnce,
    который описывает замыкания, вызываемые только один раз
  • трейт dyn Trait,
    который позволяет создавать трейт-объекты для динамического вызова
  • трейт Trait Bound,
    который задаёт ограничения на обобщённые типы
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить