生命周期参数化结构上方法的正确类型是什么?
What is the correct type for a method on a lifetime-parameterized 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
的生命周期与函数指针参数的生命周期联系起来,但编译器一定看到了我没有看到的东西。
不幸的是,在结构 Alpha
上实现的函数 alpha
有效地将结构的生命周期作为参数,尽管实际上并没有使用它。这是在具有生命周期的结构上定义方法的语法限制。因此,即使可以将指向它的指针作为 for<'z> fn(&Alpha<'z>) -> u8
,也不能将其视为 fn(&Alpha) -> u8
,即使定义表明这应该是可能的。
这可以通过定义一个函数来解决,该函数调用该方法并取一个指向它的指针:
fn workaround(a: &Alpha) -> u8 { Alpha::alpha(a) }
Try1(workaround);
其实反过来做可能更好,在函数中定义,调用函数的方法。然后,当通过 fn(&Alpha) -> u8
指针调用该函数时,不需要第二次跳转到该方法,并且可以将对该方法的调用内联为对该函数的调用。
我有一个包含引用的结构,因此它有一个生命周期参数。我想传递这个结构的方法的函数指针。稍后,我将使用该结构的实例调用该函数。我 运行 在尝试存储函数指针时陷入困境,最终找到了这个解决方案:
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
的生命周期与函数指针参数的生命周期联系起来,但编译器一定看到了我没有看到的东西。
不幸的是,在结构 Alpha
上实现的函数 alpha
有效地将结构的生命周期作为参数,尽管实际上并没有使用它。这是在具有生命周期的结构上定义方法的语法限制。因此,即使可以将指向它的指针作为 for<'z> fn(&Alpha<'z>) -> u8
,也不能将其视为 fn(&Alpha) -> u8
,即使定义表明这应该是可能的。
这可以通过定义一个函数来解决,该函数调用该方法并取一个指向它的指针:
fn workaround(a: &Alpha) -> u8 { Alpha::alpha(a) }
Try1(workaround);
其实反过来做可能更好,在函数中定义,调用函数的方法。然后,当通过 fn(&Alpha) -> u8
指针调用该函数时,不需要第二次跳转到该方法,并且可以将对该方法的调用内联为对该函数的调用。