fn() -> ()
- указатель на функцию. *const fn() -> ()
и *mut fn() -> ()
являются указателями на функциональные указатели .
Вы хотите использовать гораздо более простой код, что также означает, что между этими двумя реализациями нет никакой разницы:
#[derive(Debug, Eq, PartialEq)]
pub struct FunctionHolder {
function: Option<ExternFn>,
}
impl FunctionHolder {
pub fn new() -> Self {
FunctionHolder {
function: Some(test_fn as ExternFn),
}
}
pub fn call(&self) {
if let Some(f) = self.function {
unsafe { f(); }
}
}
}
Как упоминалось в комментариях, взятие изменяемой ссылки на литеральное значение каждый раз создает новое значение:
fn main() {
println!("{:p}", &42);
println!("{:p}", &42);
println!("{:p}", &42);
println!("{:p}", &mut 42);
println!("{:p}", &mut 42);
println!("{:p}", &mut 42);
}
0x55a551c03a34
0x55a551c03a34
0x55a551c03a34
0x7ffd40dbb95c
0x7ffd40dbb9bc
0x7ffd40dbba1c
Неизменные ссылки на литералы имеют неявное продвижение static
:
let a = &42;
// More-or-less
static HIDDEN: i32 = 42;
let a = &HIDDEN;
Изменяемые ссылки на литералы desugar для эффективного:
let mut hidden: i32 = 42;
let a = &mut hidden;
Используя необработанные указатели, вы теряете поддержку средства проверки заимствования, чтобы указать, что ваши ссылки не живут достаточно долго для изменяемого случая.
Смотри также: