[英]How to create an iterator from string _and_ store it in a struct?
我正在嘗試為我的結構創建一個構造函數,它將在從文件讀取的String
上存儲一個迭代器。 問題是一旦函數返回, String
被刪除並且編譯器抱怨new() returns a value referencing data owned by the current function
。 有沒有辦法以某種方式將String
與結構相關聯,以便在返回后不會刪除它?
我想我在這里理解一個抱怨,但我不明白如何處理它,因為我希望構造函數同時處理文件讀取和迭代器創建。
pub struct CharStream<'a> {
input: std::str::Chars<'a>,
filename: String,
}
impl<'a> CharStream<'a> {
pub fn new(filename: String) -> CharStream<'a> {
let mut file = File::open(&filename).unwrap();
let mut input = String::new();
file.read_to_string(&mut input);
CharStream {
input: input.chars(), // Create an iterator over `input`
filename: filename,
}
// `input` is dropped here
}
}
我會將CharStream
重命名為FileContents
並讓它擁有文件的filename
和contents
作為String
s。 然后,當您需要生成TokenIter
以從contents
中迭代char
塊時,您可以按需創建Chars<'a>
並將其傳遞給TokenIter
。 完整示例:
use std::fs;
use std::str::Chars;
struct FileContents {
filename: String,
contents: String,
}
impl FileContents {
fn new(filename: String) -> Self {
let contents = fs::read_to_string(&filename).unwrap();
FileContents { filename, contents }
}
fn token_iter(&self) -> TokenIter<'_> {
TokenIter {
chars: self.contents.chars(),
}
}
}
struct TokenIter<'a> {
chars: Chars<'a>,
}
struct Token; // represents some chunk of chars
impl<'a> Iterator for TokenIter<'a> {
type Item = Token;
fn next(&mut self) -> Option<Self::Item> {
self.chars.next(); // call as many times as necessary to create token
Some(Token) // return created token here
}
}
fn example(filename: String) {
let file_contents = FileContents::new(filename);
let tokens = file_contents.token_iter();
for token in tokens {
// more processing here
}
}
String::chars()
返回的迭代器僅在原始字符串input
存在時才有效。 input
在new
的末尾被刪除,因此無法從 function 返回迭代器。
為了解決這個問題,您還希望將input
字符串存儲在結構中,但隨后您會遇到其他問題,因為一個結構成員不能引用同一結構的另一個成員。 這樣做的一個原因是結構將變得不可移動,因為移動它會使引用無效。
最簡單的解決方案可能是將char
收集到Vec<char>
並將該向量存儲在CharStream
中。 然后添加一個usize
索引並編寫您自己的Iterator<Item = char>
實現。
另一種方法(更節省內存)是存儲String
本身,並按需創建Chars
迭代器,但這當然會導致不同的 API。
涉及RefCell
或類似包裝器的解決方案也可能是可能的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.