Цитировать Fn
черта документы :
Эта черта (Fn
)не путать с функциональными указателями (fn
).
Функциональные указатели не позволяют иметь состояние в виде замыкания.Если вы используете что-то вроде функции sigmoid
, которая определена без состояния, вы можете использовать это.Если вы используете замыкание с состоянием, вам нужно , чтобы иметь некоторую форму динамической отправки или универсального типа, потому что вы не можете назвать тип замыкания.
Например, с помощью fn
poitners:
struct Foo {
my_func: fn(f64) -> f64
}
Или с динамической рассылкой и ссылками:
struct Foo<'a> {
my_func: &'a dyn Fn(f64) -> f64,
}
или с изменяемым состоянием:
struct Foo<'a> {
my_func: &'a mut dyn FnMut(f64) -> f64,
}
Без продолжительности жизни:
struct Foo {
my_func: Box<dyn FnMut(f64) -> f64>
}
Я думаю, что при сохранении его в куче будет и снижение производительности, или я здесь ошибаюсь?
Да, частоштраф с динамической диспетчеризацией из-за двойной косвенности прохождения vtable. Я верю , я не уверен, есть также наказание из-за отсутствия мономорфизации.Но они оба не важны, если они не поддаются количественной оценке.
pub const SIGMOID: Fn(f64) -> f64 = |x| 1.0 / (1.0 + E.powf(x));
Это может стать
pub const SIGMOID: fn(f64) -> f64 = |x| 1.0 / (1.0 + E.powf(x));
И fn
указателями реализовать все Fn*
черты:
Кроме того, функциональные указатели любая подпись, ABI или безопасность являются Copy
, и все безопасные функциональные указатели реализуют Fn
, FnMut
и FnOnce
.Это работает, потому что эти черты специально известны компилятору.