Это не так. У вас может быть неправильная ментальная модель того, как работают замыкания.
Закрытие представляет собой просто синтаксическую короткую руку для функции с дополнительным начальным аргументом, который захватывает значения из определяющей среды. Мы можем переписать пример на то, что является логически эквивалент:
fn factory() -> Box<Closure> {
let num = 5;
Box::new(Closure { num: num })
}
struct Closure {
num: i32,
}
impl Closure {
pub fn invoke(&self, x: i32) -> i32 {
x + self.num
}
}
fn main() {
let f = factory();
let answer = f.invoke(1);
assert_eq!(6, answer);
}
Обратите внимание, как num
получает захвачены в «замыкание» в точке «закрытия» строится. Тело замыкания обращается к нему через self
(который отмахивается для реальных закрытий).
Единственное различие между это и исходным кодом является то, что:
Тип Closure
существует, но анонимного. То есть вы не можете называть тип напрямую, и, следовательно, вы должны использовать Fn(i32) -> i32
в возвращаемом типе.
Из-за вышеизложенного мы возвращаем коробчатый конкретный тип, а не объект в виде штриховки. Что касается того, как используется «закрытие», это не имеет большого значения для нас. Причина, по которой мы не можем вернуться Box<Fn(i32) -> i32>
, состоит в том, что ...
Мы не реализуем Fn
. Этого еще нельзя сделать в стабильном коде. Если бы мы могли, это было бы почти идентично методу invoke
.
Мы определяем тело «замыкания» вне функции factory
. Тем не менее, это просто синтаксическая разница: тело замыкания больше не является «частью» вашего factory
, чем тело invoke
является «частью» для выполнения этогоfactory
.
Итак, мы надеемся, вы можете увидеть, что выполнение делает не возврата к функции factory
: она переходит в другую функцию, которая просто случается определяется в factory
ради удобства.
Это очень полезно! Благодарю. – enaJ