简体   繁体   English

由于需求冲突,结构中的访问引用无法推断借用表达式的适当生存期

[英]access reference in struct causes cannot infer an appropriate lifetime for borrow expression due to conflicting requirements

I'm implementing a web service using tonic grpc crate.我正在使用 tonic grpc crate 实现一个 Web 服务。 Here is the my code:这是我的代码:

use std::cell::RefCell;
use std::ops::{Deref, DerefMut};
use std::sync::Mutex;


fn main() {
    let my_struct = MyStruct {data_ref: RefCell::new(None), data: vec![MyData(28)]};
    my_struct.my_fun();
    // my_struct.my_fun_is_gone(); This is not working.
    println!("{}", my_struct.data_ref.borrow().deref().unwrap().0);
}

/// AUTO GENERATED CODE OR THIRD PARTY TRAITS
///for example tonic generated Grpc services
trait TonicGeneratedGrpcService {
    fn my_fun_is_gone(&self); //so I Can't change the &self lifetime parameter
}

struct MyData(u8);
struct MyStruct<'a> {
    data: Vec<MyData>, //this struct is owns this property, there is no any problem
    data_ref: RefCell<Option<&'a MyData>>, //And sometimes I want to save the data
}

impl<'a> TonicGeneratedGrpcService for MyStruct<'a> {
    fn my_fun_is_gone(&self) { //I can't change the &self lifetime parameter because this is just an implementation of some super traits, change the lifetime parameters also requires change the super trait's method's lifetime.

//***********COMPILER ERROR is occurred HERE, how can I make this working?*************
        let some_of_data = &self.data[0]; //Maybe &self.data[1], &self.data[2]...
        *self.data_ref.borrow_mut() = Some(some_of_data);
    }
}

impl<'a> MyStruct<'a> {
    //Below code is works fine if this is myself defined method, but I can't change the lifetime of "self" in super traits if this is a implementation of tonic generated service or other third party traits
    fn my_fun(&'a self) {
        let some_of_data = &self.data[0]; //Maybe &self.data[1], &self.data[2]...
        *self.data_ref.borrow_mut() = Some(some_of_data);
    }
}

My final purpose is save the reference that one of the Vec<MyData> into data_ref field at runtime by some conditions.我的最终目的是通过某些条件在运行时将Vec<MyData>之一的引用保存到 data_ref 字段中。

Here is the compiler error:这是编译器错误:

error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
  --> src/main.rs:28:29
   |
28 |         let some_of_data = &self.data[0]; //Maybe &self.data[1], &self.data[2]...
   |                             ^^^^^^^^^^^^
   |
note: first, the lifetime cannot outlive the anonymous lifetime defined here...
  --> src/main.rs:26:23
   |
26 |     fn my_fun_is_gone(&self) { //I can't change the &self lifetime parameter because this is just an implementation of some super traits,...
   |                       ^^^^^
note: ...so that reference does not outlive borrowed content
  --> src/main.rs:28:29
   |
28 |         let some_of_data = &self.data[0]; //Maybe &self.data[1], &self.data[2]...
   |                             ^^^^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined here...
  --> src/main.rs:25:6
   |
25 | impl<'a> TonicGeneratedGrpcService for MyStruct<'a> {
   |      ^^
note: ...so that the expression is assignable
  --> src/main.rs:29:39
   |
29 |         *self.data_ref.borrow_mut() = Some(some_of_data);
   |                                       ^^^^^^^^^^^^^^^^^^
   = note: expected `Option<&'a MyData>`
              found `Option<&MyData>`

I can't change the source code of TonicGeneratedGrpcService trait because it may be in the third party crate or auto generated code, and now I cannot find any way to make work the my_fun_is_gone method implementation.我无法更改TonicGeneratedGrpcService特征的源代码,因为它可能在第三方 crate 或自动生成的代码中,现在我找不到任何方法来实现my_fun_is_gone方法的实现。

Should I avoid the lifetime and use reference counted pointers ( Rc , Arc ) rather then save reference ( &MyData ) directly in struct MyStruct ?我应该避免生命周期并使用引用计数指针( RcArc )而不是直接在 struct MyStruct中保存引用( &MyData )吗? Or there any way to make work this?或者有什么办法可以做到这一点?

As others said, Rust's lifetime system doesn't allow self-referential struct.正如其他人所说,Rust 的生命周期系统不允许自引用结构。

To solve this, you may directly store the index integer in the data_ref if data vec is only appended.为了解决这个问题,如果仅附加data vec,您可以直接将索引整数存储在data_ref中。 Depending on your use case, you can also consider other options here Why can't I store a value and a reference to that value in the same struct?根据您的用例,您还可以在此处考虑其他选项为什么我不能将值和对该值的引用存储在同一个结构中?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 由于需求冲突,无法为借用表达式推断出适当的生命周期 - cannot infer an appropriate lifetime for borrow expression due to conflicting requirements 由于需求冲突,无法推断借用表达式的适当生存期 - Cannot infer an appropriate lifetime for borrow expression due to conflicting requirement(s) 由于递归结构中的冲突要求,无法推断出适当的生命周期 - Cannot infer an appropriate lifetime due to conflicting requirements in a recursive struct 由于需求冲突,无法推断出合适的生命周期 - Cannot infer an appropriate lifetime due to conflicting requirements 将结构转换为具有生存期的特征得到“由于需求冲突,无法为生存期参数&#39;a&#39;推断适当的生存期” - casting struct to trait with lifetime got “cannot infer an appropriate lifetime for lifetime parameter `'a` due to conflicting requirements” 由于对由具有 Serde Deserialize 的枚举组成的结构的要求相互冲突,因此无法为生命周期参数“de”推断合适的生命周期 - cannot infer an appropriate lifetime for lifetime parameter `'de` due to conflicting requirements for struct made of enums with Serde Deserialize 尝试将具有生命周期的返回值设置为结构时,由于存在冲突的要求,无法推断出 autoref 的适当生命周期 - Cannot infer an appropriate lifetime for autoref due to conflicting requirements when tried to set a return value with lifetime to a struct 由于需求冲突,无法为 autoref 推断适当的生命周期 - Cannot infer an appropriate lifetime for autoref due to conflicting requirements 作为函数参数的闭包“由于需求冲突而无法推断出适当的寿命” - Closure as function parameter “cannot infer an appropriate lifetime due to conflicting requirements” Rust:由于要求冲突,无法推断 autoref 的适当生命周期 - Rust: cannot infer an appropriate lifetime for autoref due to conflicting requirements
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM