如何为创建具有特征生命周期边界的对象的生产者找到通用边界
How to find generic bounds for producer that creates objects with trait-lifetime bounds
我已将我的实际代码缩减为这个最小示例:
trait Producer<P> where P: Something {
fn produce(&self) -> Box<P>;
}
struct P1 {}
impl Producer<B1> for P1 {
fn produce(&self) -> Box<B1> {
Box::new(B1 {})
}
}
trait Something {}
trait Borrower<'b> {
type B: std::fmt::Display;
fn borrow(&'b self) -> Self::B;
}
struct B1 {}
impl Something for B1 {}
impl<'b> Borrower<'b> for B1 {
type B = Borrowing1<'b>;
fn borrow(&'b self) -> Self::B {
Borrowing1 { _b: &self }
}
}
struct Borrowing1<'b> {
_b: &'b B1,
}
impl<'b> std::fmt::Display for Borrowing1<'b> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Borrowing1")
}
}
fn perform<'b, P, B>(producer: P) where P: Producer<B>, B: Something + Borrower<'b> + 'static {
for _ in 0..1 {
let b = producer.produce();
let s = b.borrow().to_string();
eprintln!("{}", s);
}
}
fn main() {
let p1 = P1 {};
perform(p1);
}
我有一个创建 Something
的 Producer
类型。而那个东西可以实现Borrower<'b>
,它引入了一个生命周期。然后,我想限制函数 perform
来接收生产 Something
且具有 Borrower<'b>
特征的生产者。但是,由于我无法阻止在 perform
中引入生命周期,因此该函数认为所有生成的项目都必须在整个函数执行期间存在。实际上,它们是只是实现 Borrower<'b>
的静态对象。但我很难找到正确的界限。
错误消息反映:
error[E0597]: `*b` does not live long enough
--> src/main.rs:46:17
|
43 | fn perform<'b, P, B>(producer: P) where P: Producer<B>, B: Something + Borrower<'b> + 'static {
| -- lifetime `'b` defined here
...
46 | let s = b.borrow().to_string();
| ^---------
| |
| borrowed value does not live long enough
| argument requires that `*b` is borrowed for `'b`
47 | eprintln!("{}", s);
48 | }
| - `*b` dropped here while still borrowed
也许你可以帮我。
这可以用higher-rank trait bounds解决:
你不必过一辈子才能在这里发挥作用。相反,您需要在调用 borrow()
时定义生命周期。以下应该可以解决问题:
fn perform<P, B>(producer: P)
where
P: Producer<B>,
for<'b> B: Something + Borrower<'b> + 'static,
{
for _ in 0..1 {
let b = producer.produce();
let u = b.borrow();
let s = u.to_string();
eprintln!("{}", s);
}
}
这里很好地解释了更高级别的特征边界:
我已将我的实际代码缩减为这个最小示例:
trait Producer<P> where P: Something {
fn produce(&self) -> Box<P>;
}
struct P1 {}
impl Producer<B1> for P1 {
fn produce(&self) -> Box<B1> {
Box::new(B1 {})
}
}
trait Something {}
trait Borrower<'b> {
type B: std::fmt::Display;
fn borrow(&'b self) -> Self::B;
}
struct B1 {}
impl Something for B1 {}
impl<'b> Borrower<'b> for B1 {
type B = Borrowing1<'b>;
fn borrow(&'b self) -> Self::B {
Borrowing1 { _b: &self }
}
}
struct Borrowing1<'b> {
_b: &'b B1,
}
impl<'b> std::fmt::Display for Borrowing1<'b> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "Borrowing1")
}
}
fn perform<'b, P, B>(producer: P) where P: Producer<B>, B: Something + Borrower<'b> + 'static {
for _ in 0..1 {
let b = producer.produce();
let s = b.borrow().to_string();
eprintln!("{}", s);
}
}
fn main() {
let p1 = P1 {};
perform(p1);
}
我有一个创建 Something
的 Producer
类型。而那个东西可以实现Borrower<'b>
,它引入了一个生命周期。然后,我想限制函数 perform
来接收生产 Something
且具有 Borrower<'b>
特征的生产者。但是,由于我无法阻止在 perform
中引入生命周期,因此该函数认为所有生成的项目都必须在整个函数执行期间存在。实际上,它们是只是实现 Borrower<'b>
的静态对象。但我很难找到正确的界限。
错误消息反映:
error[E0597]: `*b` does not live long enough
--> src/main.rs:46:17
|
43 | fn perform<'b, P, B>(producer: P) where P: Producer<B>, B: Something + Borrower<'b> + 'static {
| -- lifetime `'b` defined here
...
46 | let s = b.borrow().to_string();
| ^---------
| |
| borrowed value does not live long enough
| argument requires that `*b` is borrowed for `'b`
47 | eprintln!("{}", s);
48 | }
| - `*b` dropped here while still borrowed
也许你可以帮我。
这可以用higher-rank trait bounds解决:
你不必过一辈子才能在这里发挥作用。相反,您需要在调用 borrow()
时定义生命周期。以下应该可以解决问题:
fn perform<P, B>(producer: P)
where
P: Producer<B>,
for<'b> B: Something + Borrower<'b> + 'static,
{
for _ in 0..1 {
let b = producer.produce();
let u = b.borrow();
let s = u.to_string();
eprintln!("{}", s);
}
}
这里很好地解释了更高级别的特征边界: