借来的价值在 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);
}
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())
}
}
}
此代码无法编译,因为 Error 包含对 value 的引用,但是当作用域退出时 value 被销毁,但 Error 继续存在
这是我遇到的问题的一个极简示例。以下代码产生以下错误。我刚遇到这个 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);
}
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())
}
}
}
此代码无法编译,因为 Error 包含对 value 的引用,但是当作用域退出时 value 被销毁,但 Error 继续存在