Rust:为什么克隆和/或复制的值存在引用错误?

问题描述 投票:0回答:1

我不知道是什么导致了这个引用错误:

error[E0515]: cannot return value referencing local variable `s1`
   --> src/regexp/mod.rs:538:9
    |
528 |             match s1.step() {
    |                   --------- `s1` is borrowed here
...
538 |         steps
    |         ^^^^^ returns a value referencing data owned by the current function

For more information about this error, try `rustc --explain E0515`.
error: could not compile `regexp` due to previous error

我已经制作了 CharsStep 结构克隆和复制,并且在两次推送中我都尝试了推送对象的克隆并进行分配以获取副本并推送它。我以为我正在理解内存模型,但是这个让我卡住了。这里借的是什么?在添加到步骤向量之前,不是所有的引用都被复制了(多次!)吗?

我查看了建议的参考,它只是解释了我所知道的,我只能返回值,而不是对本地值的引用,但由于它们是克隆的,我认为它们没问题。

pub trait Walker {}
    
// used to hold the state at each step in the search walk, and later to build the final result if successful
#[derive(Clone, Copy)]
struct CharsStep<'a> {
    node: &'a CharsNode,
    string: &'a str,
    matched: &'a str,
}

impl<'a> Walker for CharsStep<'a> {}

impl<'a> CharsStep<'a> {
    fn walk(node: &'a CharsNode, string: &'a str) -> Vec<Box<dyn Walker + 'a>> {
        let mut steps = Vec::<Box<dyn Walker>>::new();
        let mut step = CharsStep {
            node,
            string,
            matched: "",
        };
        if node.limit_desc.0 == 0 {
            steps.push(Box::new(step.clone()));
        }

        for i in 1..node.limit_desc.1 {
            let s1 = step;
            match s1.step() {
                Some(s) => {
                    if i >= node.limit_desc.0 {
                        steps.push(Box::new(s.clone()));
                    }
                    step = s.clone();
                }
                None => {
                    break;
                }
            }
        }
        steps
    }
    
    fn step(&self) -> Option<CharsStep> {
        let len = self.node.string.len();
        if self.string[0..len] == self.node.string {
            Some(CharsStep {
                node: self.node,
                string: &self.string[len..],
                matched: &self.string[..len],
            })
        } else {
            None
        }
    }
}
rust lifetime borrow-checker
1个回答
1
投票

我很惊讶没有关于这个的警告(甚至是 Clippy lint)。

你忘记了一个lifetime annotation,实质上改变了意思:

    fn step(&self) -> Option<CharsStep> {

这被解释为好像你写了:

    fn step<'s>(&'s self) -> Option<CharsStep<'s>> {

当您调用

step
时,会创建一个临时引用,因为
step
需要
&self
。由于缺少此生命周期注解,编译器说您正在借用当前函数拥有的数据是非常正确的。它只能看函数签名,这就是它所说的。

由于您实际上是从

self
借用数据,因此您需要将其更改为与那里引用的数据具有相同的生命周期,即来自 impl 上下文的
'a

    fn step(&self) -> Option<CharsStep<'a>> {
© www.soinside.com 2019 - 2024. All rights reserved.