Коли закриття реалізує Fn, FnMut і FnOnce?


114

Які специфічні умови для закриття в цілях здійснення Fn, FnMutі FnOnceриси?

Це є:

  • Коли закриття не реалізує FnOnceознаку?
  • Коли закриття не реалізує FnMutознаку?
  • Коли закриття не реалізує Fnознаку?

Наприклад, мутація стану закриття на його тілі змушує компілятор не реалізувати Fnйого.


11

Відповіді:


126

Кожні ознаки представляють все більш і більш обмежуючі властивості щодо закриттів / функцій, що позначаються підписами їх call_...методу, зокрема типом self:

  • FnOnce( self) - це функції, які можна викликати один раз
  • FnMut( &mut self) - це функції, які можна викликати, якщо вони мають &mutдоступ до свого оточення
  • Fn( &self) - це функції, які можна викликати, якщо вони мають лише &доступ до свого оточення

Закриття |...| ...автоматично реалізує стільки, скільки можливо.

  • Усі закриття реалізують FnOnce: закриття, яке не можна викликати один раз, не заслуговує назви. Зауважте, що якщо закриття реалізується лише FnOnceвоно, його можна викликати лише один раз.
  • Закриття, яке не рухається зі своїх знімань, реалізовує FnMut, дозволяючи викликати їх не раз (якщо є недостовірний доступ до об'єкта функції).
  • Замикання, які не потребують унікального / змінного доступу до своїх знімальних програм Fn, дозволяють викликати їх по суті всюди.

Ці обмеження випливають безпосередньо з типу selfта "знебарвлення" закриттів у конструкції; описаний у моєму дописі в блозі Пошук закриття в Іржі .

Інформацію про закриття див. У розділі Закриття: Анонімні функції, які можуть зафіксувати їхнє середовище мовою програмування іржі .


Якщо закриття реалізовується лише FnOnceчи означає це, що його можна викликати лише один раз?
nalply

@nalply, так, лише один раз.
хуно

9
Я неправильно прочитав коментар nalply, і це викликало в мене деяку плутанину. Майбутні читачі, будь ласка, зверніть увагу, що він сказав, "якщо закриття лише буде здійснено FnOnce".
сонник

2
Деталізація щодо впровадження: автоматично реалізує стільки, скільки можливо. це не зовсім вірно, він реалізує їх автоматично, якщо здається, що це потрібно. Ви можете виявити відсутні Fn-impl для закриття, яке було використано для аргументу FnMut, використовуючи спеціалізацію. Це помилка github.com/rust-lang/rust/isissue/26085
bluss
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.