Будет ли черта Copy автоматически выводиться в Rust?

fn fn_once<F>(func: F)
where
    F: FnOnce(usize) -> bool, 
{
    println!("{}", func(3));
    println!("{}", func(4));
}

fn main() {
    let x = 3;
    fn_once(|z| z == x)
}

Приведенный выше код сообщает об ошибке [E0382]: использование перемещенного значения: func.

Ошибка исчезает после добавления ограничения типажа Copy:

fn fn_once<F>(func: F)
where
    F: FnOnce(usize) -> bool + Copy, 
{
    println!("{}", func(3));
    println!("{}", func(4));
}

fn main() {
    let x = 3;
    fn_once(|z| z == x)
}

Мой вопрос: эта черта копирования получена автоматически, потому что я указал привязку к черте? Или само замыкание всегда имело свойство Copy, и оно вступает в силу только после указания привязки копирования?

Я хочу знать, какой механизм стоит за этим.

Почему Python в конце концов умрет
Почему Python в конце концов умрет
Последние 20 лет были действительно хорошими для Python. Он прошел путь от "просто языка сценариев" до основного языка, используемого для написания...
1
0
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Замыкания, которые захватывают только типы Copy, автоматически реализуются Copy.

Но дженерики Rust проверяются по определениям. Не имеет значения, как вы это назовете (на самом деле, вы получите ошибку даже при компиляции fn_once в одиночку, без каких-либо вызывающих программ). Сигнатура функции должна быть достаточной, чтобы разрешить использование всего, что находится внутри. Поэтому, если вы не укажете Copy, компилятор предположит, что тип не будет Copy, и соответствующим образом проверит код.

Тем не менее, FnOnce предназначен для однократного вызова, он заложен в названии! Также указывать Copy, чтобы вы могли использовать его несколько раз, довольно бессмысленно. Вместо этого вам следует изменить FnOnce на Fn.

Fn слишком много, FnMut достаточно.
Chayim Friedman 20.07.2024 20:06

Другие вопросы по теме