我有一个包含引用的结构,因此它有一个生命周期参数。我想传递这个结构的方法的函数指针。稍后,我将使用struct的实例调用该函数。我在尝试存储函数指针时碰到了障碍,最终找到了这个解决方案:
struct Alpha<'a> { a: &'a u8 }
impl<'a> Alpha<'a> {
fn alpha(&self) -> u8 { *self.a }
}
struct Try1(fn(&Alpha) -> u8);
struct Try2(for<'z> fn(&Alpha<'z>) -> u8);
struct Try3<'z>(fn(&Alpha<'z>) -> u8);
fn main() {
Try1(Alpha::alpha); // Nope
Try2(Alpha::alpha); // Nope
Try3(Alpha::alpha);
}
不幸的是,这个解决方案对我的实际情况不起作用,因为我想实现一个有自己生命概念的特征:
trait Zippy {
fn greet<'a>(&self, &Alpha<'a>);
}
impl<'z> Zippy for Try3<'z> {
fn greet<'a>(&self, a: &Alpha<'a>) { println!("Hello, {}", self.0(a)) }
}
产生错误:
error: mismatched types:
expected `&Alpha<'z>`,
found `&Alpha<'a>`
我觉得我不需要将结构Try3
的生命周期与函数指针参数的生命周期联系起来,但编译器必须看到我不是的东西。
答案 0 :(得分:1)
不幸的是,结构alpha
上实现的函数Alpha
有效地将struct的生命周期作为参数,尽管实际上并没有使用它。这是使用生命周期定义结构的方法的语法限制。因此即使可以将指针指向for<'z> fn(&Alpha<'z>) -> u8
,也不可能将其视为fn(&Alpha) -> u8
,即使定义表明这应该是可能的。
这可以通过定义一个调用该方法的函数并改为使用指针来解决它:
fn workaround(a: &Alpha) -> u8 { Alpha::alpha(a) }
Try1(workaround);
事实上,以相反的方式执行它可能会更好,函数中的定义和调用函数的方法。然后,当通过fn(&Alpha) -> u8
指针调用该函数时,方法中不需要第二次跳转,并且可以将对该方法的调用内联为对该函数的调用。