价值存在时间不够长

41

我不完全了解lifetime,但我认为b的lifetime将会在self之前结束。

那么,如何编辑这段代码?我需要复制内存中的某些内容吗?如果我创建一个新的实例,它的lifetime必须符合这种情况。

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

2
你应该将 layout 声明为 String 而不是 &'static str。https://dev59.com/OWAf5IYBdhLWcg3w52I_ - kennytm
1
谢谢,这可以帮助我完成它。但是,如果我想使用 &str,该怎么办?Rust 不能直接编辑生命周期吗? - 彭灵俊
@彭灵俊 你为什么想要使用 &str - wimh
我对Formater中的&'部分不太明白,因为b并不是一个静态字符串,你不能给它一个静态引用,对吗? - Netwave
1个回答

31
b的作用域是new函数,因此它的内存将在函数返回时被释放。但是您正在尝试从该函数返回对b的引用。如果Rust让您这样做,唯一可能使用该引用的代码将在值无效后使用它。借用检查器保护您免受未定义行为的损害。
layout设置为&'static str似乎使事情变得简单,但是预期来自regex.replace_all的动态分配的内存是静态的是不合理的。如果不涉及unsafe代码,请考虑'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拥有,所以只要它仅用于比main作用域更小的范围内,formatter就是有效的。

但总的来说,我认为这种方法更加混乱,除非你有充分的理由,否则应坚持使用String


布局:&'a mut &str。我不太明白类型签名中为什么会有两个“&”符号。我对Rust还很陌生。一个是借用,另一个是引用吗?难道借用不就是引用吗?我感到困惑。 - Lunfel
2
@Lunfel 引用是借用。这是引用的引用。因此这是一个借用上的借用。一切都没问题。 - nuts-n-bits

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接