string - 如何在知道需要多大之前分配一个字符串

标签 string rust lifetime

我敢肯定这是初学者的错误。我的代码是:

...
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/

相关文章:

c++ - 正则表达式匹配整个字符串

C++ - 临时变量及其生命周期

ios - 截断 UILabel 和 UITextField 中的第一个字母而不是最后一个字母?

C - 获取 double 字的位数

rust - 从具有自链接生命周期的可变引用获取不可变引用时有什么区别?

rust - 无法从 `i32` 构建类型为 `std::iter::Iterator<Item=_>` 的集合

multithreading - 如何在 Iron 框架中启用线程功能?

rust - 当编译器建议使用 move 关键字时,我应该怎么做才能使迭代器中的生命周期起作用?

generics - 特征上的链接函数

java - 如何从字符串中删除除 - 之外的所有特殊字符。和空间