gpt4 book ai didi

functional-programming - 在匹配中折叠引用会导致生命周期错误

转载 作者:行者123 更新时间:2023-11-29 08:10:12 26 4
gpt4 key购买 nike

我想通过迭代简单结构的向量来构建字符串 s,根据结构将不同的字符串附加到 acc

#[derive(Clone, Debug)]
struct Point(Option<i32>, Option<i32>);

impl Point {

fn get_first(&self) -> Option<i32> {
self.0
}

}

fn main() {

let mut vec = vec![Point(None, None); 10];
vec[5] = Point(Some(1), Some(1));


let s: String = vec.iter().fold(
String::new(),
|acc, &ref e| acc + match e.get_first() {
None => "",
Some(ref content) => &content.to_string()
}
);

println!("{}", s);

}

运行此代码会导致以下错误:

error: borrowed value does not live long enough
Some(ref content) => &content.to_string()
^~~~~~~~~~~~~~~~~~~
note: reference must be valid for the expression at 21:22...
|acc, &ref e| acc + match e.get_first() {
^
note: ...but borrowed value is only valid for the expression at 23:33
Some(ref content) => &content.to_string()
^~~~~~~~~~~~~~~~~~~~

问题是我创建的 &str 的生命周期似乎会立即结束。但是,如果 to_string() 首先返回一个 &str,编译器就不会报错。那么,有什么区别呢?

如何让编译器理解我希望字符串引用在我构造 时一直存在?

最佳答案

你的分支结果有区别:

  • "" 是类型 &'static str
  • contenti32 类型,因此您要将其转换为 String,然后再将其转换为 &str... 但是这个 &strto_string 返回的 String 具有相同的生命周期,它死得太早了

如@Dogbert 所述,一个快速的解决方法是将 acc + 移动到分支中:

let s: String = vec.iter().fold(
String::new(),
|acc, &ref e| match e.get_first() {
None => acc,
Some(ref content) => acc + &content.to_string(),
}
);

但是,这有点浪费,因为每次我们有一个整数时,我们都在分配一个 String(通过 to_string),只是为了立即丢弃它。

更好的解决方案是改用 write! 宏,它只是附加到原始字符串缓冲区。这意味着没有浪费的分配。

use std::fmt::Write;

let s = vec.iter().fold(
String::new(),
|mut acc, &ref e| {
if let Some(ref content) = e.get_first() {
write!(&mut acc, "{}", content).expect("Should have been able to format!");
}
acc
}
);

它可能有点复杂,主要是因为格式化增加了错误处理,但效率更高,因为它只使用一个缓冲区。

关于functional-programming - 在匹配中折叠引用会导致生命周期错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39231801/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com