Функция принимает параметр типа FnMut, то есть этот параметр может изменять своё состояние. Почему тогда в сигнатуре функции event_handler не объявлен как mut? Документация утверждает, что мутабельный параметр необходим. В качестве примера приведена функция из winit:
```rust
pub fn run<F>(self, event_handler: F) -> Result<(), EventLoopError>
where
F: FnMut(Event<T>, &EventLoopWindowTarget<T>),
{
self.event_loop.run(event_handler)
}
```
Как объяснить отсутствие явного указания на мутабельность параметра event_handler?
В Rust, когда мы говорим о "мутабельности" в контексте замыканий и типов, таких как `FnMut`, важно понимать, что мутабельность касается состояния замыкания, а не того, как мы передаем сам аргумент в функцию.
Когда вы передаете замыкание в функцию, вы не изменяете саму переменную, в которую оно заключено (в данном случае `event_handler`), вы просто передаете ее как аргумент функции. Поэтому сигнатура функции не требует, чтобы сам параметр `event_handler` был объявлен как `mut`. Однако важно то, что когда вы вызываете это замыкание (то есть когда вы вызываете `event_handler(...)` внутри функции), это замыкание может изменять своё внутреннее состояние, поскольку оно реализует трейт `FnMut`.
Таким образом, подходящий пример, который вы привели, правильно демонстрирует, что потребность в изменяемости распространяется на то, как используется замыкание (то есть, на его внутреннее состояние), а не на сам аргумент функции.
Пример использования `FnMut` выглядит так:
```rust
fn example<F>(mut handler: F)
where
F: FnMut(),
{
handler(); // Вызывая, мы можем менять состояние handler
}
// Использование
let mut count = 0;
let mut increase_count = || {
count += 1;
};
example(increase_count); // Здесь `increase_count` может изменять `count`
```
В этом примере, передавая `increase_count` в `example`, переменная `handler` в `example` не помечена как `mut`, но внутри вызывается она как `FnMut`, что позволяет изменять состояние `count`.
Мутабельность нужна для вызова, так как FnMut вызывается по мутабельной ссылке.
Здесь же только передаётся владение в метод run
P.S. что-то мне подсказывает, что сигнатура не совсем корректная. Отсутствует объявление дженерика T (и возможно его ограничений), отсутствует лайфтайм для ссылки в колбэке:pub fn run<T, F>(self, event_handler: F) -> Result<(), EventLoopError> where F: for<'a> FnMut(Event<T>, &'a EventLoopWindowTarget<T>), { self.event_loop.run(event_handler) }
Потому что замыкание, которое не имеет мутабельных ссылок на окружение - автоматически реализует трейты Fn, FnMut и FnOnce.
В функции run указан самый широкий вариант из возможных (Fn обычный был бы слишком узким, а FnOnce для run не подходит, тк замыкание предполагается вызывать много раз)
https://habr.com/ru/articles/588917/
https://stackoverflow.com/questions/30177395/when-...