gpt4 book ai didi

json - Rust 变量 'does not live long enough' 和 'conflicting requirements'

转载 作者:行者123 更新时间:2023-11-29 08:07:48 25 4
gpt4 key购买 nike

不幸的是,我在管理 Rust 中与字符串和结构相关的生命周期时遇到了很多麻烦。

#[macro_use]
extern crate serde_derive;
extern crate serde_json;
use serde_json::Value;
use std::fs::File;
use std::path::Path;
use std::io::prelude::*;
use std::fs;
use std::cell::RefCell;

#[derive(Serialize, Deserialize, Debug)]
struct Song {
artist: String,
}

struct SongEntry {
date: &'static str,
song: &'static Song,
}

fn main() {
let paths = fs::read_dir("./charts/").unwrap();

let fileContents = paths.map(| path | {
let p = path.unwrap().path();
let file = File::open(&p).unwrap();
let v: Vec<Song> = serde_json::from_reader(file).unwrap();
return v.iter().map(move | song | {
let date = p.file_stem().unwrap().to_str().unwrap();
return SongEntry {
song: song,
date: date,
};
})
});
}

我在这里尝试了许多管理内存的变体,但似乎只是将一个错误换成另一个错误。

目的是遍历目录中的 JSON 文件,解析它们,并组装一个包含日期(来自文件名)和内容(来自已解析的 JSON)的对象向量。

到目前为止,我已尝试在内部 map 内或外部声明 date,尝试使用 Arc 来管理 >date 变量,尝试使用和不使用 move 关键字的内部循环。

但是,我就是找不到一种方法让这些 map 方法中的变量绑定(bind)持续适当的时间。任何帮助将不胜感激。

当前产生的错误是:

   Compiling kanye v0.1.0 (file:///Users/tmcw/src/sandbox/kanye)
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in function call due to conflicting requirements
--> src/main.rs:29:26
|
29 | let date = p.file_stem().unwrap().to_str().unwrap();
| ^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime as defined on the body at 28:42...
--> src/main.rs:28:43
|
28 | return v.iter().map(move | song | {
| ___________________________________________^ starting here...
29 | | let date = p.file_stem().unwrap().to_str().unwrap();
30 | | return SongEntry {
31 | | song: song,
32 | | date: date,
33 | | };
34 | | })
| |_________^ ...ending here
note: ...so that closure can access `p`
--> src/main.rs:29:24
|
29 | let date = p.file_stem().unwrap().to_str().unwrap();
| ^
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that reference does not outlive borrowed content
--> src/main.rs:32:23
|
32 | date: date,
| ^^^^

error: aborting due to previous error

error: Could not compile `kanye`.

To learn more, run the command again with --verbose.

元问题:这是在 Rust 中对 map 的适当使用,还是我应该改用普通迭代?我之前也尝试过迭代,但也被内存检查阻碍了。

最佳答案

如果您想将引用存储在结构中,那么这些引用必须指向拥有比该结构更长寿的所有者的对象。此外,&'static 引用必须引用在整个程序执行期间有效的对象。 datesong 字段都不成立。

在这里,SongEntry 结构应该只拥有 datesong 对象。

struct SongEntry {
date: String,
song: Song,
}

对于date 字段,只需将字符串切片(&str) 转换为一个拥有的字符串(String) 与to_string方法。对于 song 字段,您需要从向量 v 中移动所有权。然而,Vec::iter只产生对其项目的借用引用。您必须使用 Vec::into_iter相反,它直接返回值,并在此过程中消耗向量。

fn main() {
let paths = fs::read_dir("./charts/").unwrap();

let file_contents = paths.map(|path| {
let p = path.unwrap().path();
let file = File::open(&p).unwrap();
let v: Vec<Song> = serde_json::from_reader(file).unwrap();
v.into_iter().map(move |song| {
let date = p.file_stem().unwrap().to_str().unwrap().to_string();
SongEntry {
date: date,
song: song,
}
})
});
}

此时,file_contentsSongEntry 对象迭代器的迭代器(外部迭代器迭代文件,内部迭代器迭代文件中的条目)。如果您想直接拥有 SongEntry 对象的迭代器,请使用 flat_map而不是 paths 上的 map。然后您可以使用 collect如有必要,在最终迭代器上将结果收集到一个向量中(如果您只打算对结果进行一次迭代,请不要使用 collect!)。

关于json - Rust 变量 'does not live long enough' 和 'conflicting requirements',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42464230/

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