我敢肯定这是初学者的错误。我的代码是:
...
let mut latest_date : Option<Date<Local>> = None;
let mut latest_datetime : Option<DateTime<Local>> = None;
let mut latest_activity : Option<&str> = None;
for wrapped_line in reader.lines() {
let line = wrapped_line.unwrap();
println!("line: {}", line);
if date_re.is_match(&line) {
let captures = date_re.captures(&line).unwrap();
let year = captures.at(1).unwrap().parse::<i32>().unwrap();
let month = captures.at(2).unwrap().parse::<u32>().unwrap();
let day = captures.at(3).unwrap().parse::<u32>().unwrap();
latest_date = Some(Local.ymd(year, month, day));
println!("date: {}", latest_date.unwrap());
}
if time_activity_re.is_match(&line) && latest_date != None {
let captures = time_activity_re.captures(&line).unwrap();
let hour = captures.at(1).unwrap().parse::<u32>().unwrap();
let minute = captures.at(2).unwrap().parse::<u32>().unwrap();
let activity = captures.at(3).unwrap();
latest_datetime = Some(latest_date.unwrap().and_hms(hour, minute, 0));
latest_activity = if activity.len() > 0 {
Some(activity)
} else {
None
};
println!("time activity: {} |{}|", latest_datetime.unwrap(), activity);
}
}
...
我的错误是:
Compiling tt v0.1.0 (file:///home/chris/cloud/tt)
src/main.rs:69:55: 69:59 error: `line` does not live long enough
src/main.rs:69 let captures = time_activity_re.captures(&line).unwrap();
^~~~
src/main.rs:55:5: 84:6 note: in this expansion of for loop expansion
src/main.rs:53:51: 86:2 note: reference must be valid for the block suffix following statement 7 at 53:50...
src/main.rs:53 let mut latest_activity : Option<&str> = None;
src/main.rs:54
src/main.rs:55 for wrapped_line in reader.lines() {
src/main.rs:56 let line = wrapped_line.unwrap();
src/main.rs:57 println!("line: {}", line);
src/main.rs:58
...
src/main.rs:56:42: 84:6 note: ...but borrowed value is only valid for the block suffix following statement 0 at 56:41
src/main.rs:56 let line = wrapped_line.unwrap();
src/main.rs:57 println!("line: {}", line);
src/main.rs:58
src/main.rs:59 if date_re.is_match(&line) {
src/main.rs:60 let captures = date_re.captures(&line).unwrap();
src/main.rs:61 let year = captures.at(1).unwrap().parse::<i32>().unwrap();
...
error: aborting due to previous error
Could not compile `tt`.
我认为问题在于 latest_activity : Option<&str>
生命周期超过 line
在循环迭代中 latest_activity
被重新分配。
正确吗?
如果是这样,修复它的最佳方法是什么。分配新字符串的成本并不困扰我,尽管我不希望每次迭代都这样做。
我觉得我可能需要一个引用计数框来放置 activity
在 - 这是正确的方法吗?
我可以分配一个 String
在循环之外 - 但在我知道它需要多大之前我怎么能这样做呢?
最佳答案
问题是您已经为每次迭代分配一个新字符串(Lines
迭代器无处存储缓冲区,因此它必须为每个迭代分配一个新的String
行),但您正试图在循环外将切片存储到其中。
你也无法真正知道外部分配的 String
有多大在这种情况下需要...所以通常您不必担心它,只需根据需要调整大小即可。
最简单的方法可能是制作latest_activity
一个Option<String>
.当你想改变它时,你可以使用.clear()
其次是 .push_str(s)
(参见 String
documentation)。如果它足够大,这应该重新使用现有分配,如果不是,则调整大小。它可能需要一些重新分配,但没什么大不了的(前提是你不这样做,例如,尝试存储越来越长的字符串)。
另一种可能性是只存储 wrapped_line
本身,将其移出循环。您可以将其与切片索引一起存储,然后在循环外进行实际切片(不,您不能单独存储 String
和 &str
切片或 以及标准库类型)。
关于string - 如何在知道需要多大之前分配一个字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33781625/