生命周期参数化结构上方法的正确类型是什么?

时间:2015-01-24 03:57:49

标签: rust lifetime

我有一个包含引用的结构,因此它有一个生命周期参数。我想传递这个结构的方法的函数指针。稍后,我将使用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的生命周期与函数指针参数的生命周期联系起来,但编译器必须看到我不是的东西。

1 个答案:

答案 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指针调用该函数时,方法中不需要第二次跳转,并且可以将对该方法的调用内联为对该函数的调用。