借来的价值在 Cow 的 Vec 中存活时间不够长

Borrowed value does not live long enough with Vec of Cow

这是我遇到的问题的一个极简示例。以下代码产生以下错误。我刚遇到这个 Cow 东西,我不知道它是如何工作的。我应该如何解决这个问题?

use std::borrow::Cow;

fn main() {
    let mut v: Vec<Error> = Vec::new();
    {
        let e = Error { value: None };
        let value = "bar".to_string();
        let error = e.with_value(&value);
        v.push(error);
    }
    println!("{:?}", v);
}

// Code below here is in crate I cannot change.
#[derive(Debug)]
pub struct Error<'v> {
    pub value: Option<Cow<'v, str>>
}

impl<'v> Error<'v> {
    pub fn with_value(mut self, value: &'v str) -> Self {
        self.set_value(value);
        self
    }
    
    pub fn set_value(&mut self, value: &'v str) {
        if self.value.is_none() {
            self.value = Some(value.into());
        }
    }
}
   Compiling playground v0.0.1 (/playground)
error[E0597]: `value` does not live long enough
  --> src/main.rs:8:34
   |
8  |         let error = e.with_value(&value);
   |                                  ^^^^^^ borrowed value does not live long enough
9  |         v.push(error);
10 |     }
   |     - `value` dropped here while still borrowed
11 |     println!("{:?}", v);
   |                      - borrow later used here

For more information about this error, try `rustc --explain E0597`.
error: could not compile `playground` due to previous error

问题是您正在创建一个作用域,当该作用域退出时您的字符串被释放,因此引用无效。

fn main() {
    let mut v: Vec<Error> = Vec::new();
    
    let e = Error { value: None };
    let value = "bar".to_string();
    let error = e.with_value(&value);
    v.push(error);
    
    println!("{:?}", v);
}

Playground

Cow 可以引用,但它们仍然需要有效。你可以让它拥有:

use std::borrow::Cow;

fn main() {
    let mut v: Vec<Error> = Vec::new();
    
        let e = Error { value: None };
        let value = "bar".to_string();
        let error = e.with_owned_value(value);
        v.push(error);
    
    println!("{:?}", v);
}

// Code below here is in crate I cannot change.
#[derive(Debug)]
pub struct Error<'v> {
    pub value: Option<Cow<'v, str>>
}

impl<'v> Error<'v> {
    pub fn with_value(mut self, value: &'v str) -> Self {
        self.set_value(value);
        self
    }
    
    pub fn set_value(&mut self, value: &'v str) {
        if self.value.is_none() {
            self.value = Some(value.into());
        }
    }
    
    pub fn with_owned_value(self, value: String) -> Self {
        Self {
            value: Some(value.into())
        }
    }
}

Playground

此代码无法编译,因为 Error 包含对 value 的引用,但是当作用域退出时 value 被销毁,但 Error 继续存在