rust - 值(value)活得不够长

标签 rust lifetime borrowing

我不完全理解生命周期,但我认为 b 的生命周期会在 self 之前结束。

那么,如何编辑这段代码呢?我会在内存中复制一些东西吗?如果我创建一个新实例,此生命周期必须遵守此案例。

pub struct Formater {
    layout: &'static str,
}

impl Formater {
    pub fn new(layout: &'static str) -> Formater {
        let regex = Regex::new(r"%\{([a-z]+)(?::(.*?[^\\]))?\}").unwrap();
        let b = regex.replace_all(layout, "{}");

        return Formater {
            layout: &b,
        };
    }
}

错误:

error: `b` does not live long enough
  --> src/format.rs:16:22
   |
16 |             layout: &b,
   |                      ^ does not live long enough
17 |         };
18 |     }
   |     - borrowed value only lives until here
   |
   = note: borrowed value must be valid for the static lifetime...

最佳答案

b 的作用域是new 函数,所以它的内存会在函数返回时释放。但是您正试图从该函数返回对 b 的引用。如果 Rust 让你这样做,唯一可能使用该引用的代码将在 值无效后使用它。借用检查器正在保护您免受未定义的行为

layout 设为 &'static str 听起来像是在简化事情,但是期望从 regex.replace_all 动态分配内存是不合理的 是静态的。在不涉及不安全 代码的情况下,您应该将'static 生命周期中的任何内容视为编译时常量。例如,字符串文字。

正如其他人所说,您可能希望 layout 成为 StringString 类似于 &str,但它拥有底层 str。这意味着当您移动 String 时,底层的 str 也会随之移动。 &str 是一个引用,不能超过它所指向的 str 的所有者。


如果您真的希望它是 &str,另一种不太符合人体工学的方法是让 new() 的调用者拥有 &str,并将其作为可变引用传递。

pub struct Formatter<'a> {
    layout: &'a str,
}

impl <'a> Formatter<'a> {
    pub fn new(layout: &'a mut &str) -> Formatter<'a> {
        let regex = Regex::new(r"%\{([a-z]+)(?::(.*?[^\\]))?\}").unwrap();
        *layout = regex.replace_all(layout, "{}");

        return Formatter {
            layout: layout,
        };
    }
}

这将问题移到了调用堆栈的上一层,这意味着您传递给 new 的引用将被 new 改变。

pub fn main() {
    let mut s = "blah %{blah}";
    {
        let formatter = Formatter::new(&mut s);
        println!("{:?}", formatter.layout); // "blah {}"
    }
    println!("{:?}", s); // "blah {}"
}

现在 smain 所有,所以 formatter 是有效的,只要它只在比 更小的范围内使用主要

但总的来说,我认为这种方法比较困惑,除非你有充分的理由,否则你应该坚持使用 String

关于rust - 值(value)活得不够长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42503296/

相关文章:

rust - 未找到 `tests` 和 `src` 中使用的通用函数

generics - 有没有办法表达具有不同生命周期界限的 "same"泛型类型?

rust - 具有结构 "cannot move out of borrowed content"的向量的多次迭代

vector - 无法返回字符串切片向量 : borrowed value does not live long enough

rust - 如何在过程宏中提供有用的编译器错误?

macros - 可以检查一个值是 Rust 中的编译时间常量吗?

c++ - 异步函数调用的参数生命周期

reference - 有什么方法可以返回对在函数中创建的变量的引用?

string - 如何在不克隆字符串的情况下在 Rust 中构建灵活的多类型数据系统?

pointers - 我应该如何决定何时更适合或不适合使用原始指针?