Почему после передачи права собственности можно использовать закрытие без захвата?

Я пытаюсь разобраться в праве собственности в Rust и столкнулся с недоразумением, связанным с передачей прав собственности. Рассмотрим следующий код:

fn main() {
    let closure = || 32;
    foo(closure);
    foo(closure); //perfectly fine
}

fn foo<F>(f: F) -> u32
where
    F: Fn() -> u32,
{
    f()
}

детская площадка

Я подумал, что нужно передать право собственности и нельзя разрешать второй вызов foo(closure).

Почему это работает?


person Some Name    schedule 27.07.2020    source источник


Ответы (1)


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

fn main() {
    let v = 32;
    foo(v);
    foo(v);
}

fn foo(a: u32) -> u32 {
    a
}

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

person Shepmaster    schedule 27.07.2020
comment
Спасибо за точку. Действительно, поведение хорошо описано в справочнике : Замыкание - это Clone или Copy, если оно не захватывает никаких значений по уникальной неизменяемой или изменяемой ссылке, и если все значения, которые оно захватывает копированием или перемещением, равны Clone или Copy соответственно. - person Some Name; 27.07.2020
comment
Это своего рода оффтоп по этому конкретному вопросу, но я хотел бы прояснить один момент, касающийся захваченного закрытия. Предположим, что замыкание захватывает некоторую переменную и становится владельцем нее с move, указанным перед списком аргументов. Если ссылка на переменную используется в теле замыкания, будет ли время жизни захваченной переменной быть таким же, как у замыкания, и замыкание будет Fn, а не FnOnce? - person Some Name; 27.07.2020
comment
@SomeName move и реализованные черты характера - это две разные концепции. См. Когда закрытие реализует Fn, FnMut и FnOnce?. Вопрос о времени жизни см. В разделе Почему я не могу сохранить значение и ссылку на это значение в одной структуре?, в частности абзац, начинающийся с жизни, представляет собой немного метаданных - person Shepmaster; 27.07.2020