【问题标题】:Multiple uses of self in same function在同一功能中多次使用 self
【发布时间】:2014-12-12 02:44:57
【问题描述】:

我与借用检查器发生争执。我的问题有点复杂,但在这种情况下,我使用的是类似缓冲区的结构。我的缓冲区有一个函数safe_write_to_slot,它首先检索第一个空元素(返回 Ok(location) 或 Err(error message) 的结果),然后将值写入检索到的位置。然而问题是,当我将检索到的位置分配给一个值时,rust 抱怨说我在几行之后再次重用了 self。如何首先调用返回结果的 (self) 函数,然后继续使用 self 执行某些操作?

use std::result::Result;

struct Elems {
    pub elems : Vec<int>,
}

impl Elems {
    pub fn new() -> Elems {
        Elems{elems: vec![0,0,0,0,0,0]}
    }

    pub fn safe_write_to_slot(&mut self, elem : uint) -> Result<(), &str> {
        let loc = try!(self.get_slot());

        self.unsafe_write_to_slot(loc);

        Ok(())
    }

    pub fn get_slot(&self) -> Result<uint, &str>{
        let mut loc = -1i;

        for x in range(0, self.elems.len()) {
            if *self.elems.get(x) == 0 {
                loc = x as int;
            }
        }

        if loc != -1 { Ok(loc as uint) } else { Err("No free slots") }
    }

    fn unsafe_write_to_slot(&mut self, elem : uint) {
        self.elems[elem] = 1;
    }
}

我得到的错误是:

   Compiling borrow v0.0.1 (file:///borrow)
main.rs:19:9: 19:13 error: cannot borrow `*self` as mutable because it is also borrowed as immutable
main.rs:19         self.unsafe_write_to_slot(loc);
                   ^~~~
main.rs:17:24: 17:28 note: previous borrow of `*self` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `*self` until the borrow ends
main.rs:17         let loc = try!(self.get_slot());
                                  ^~~~
/main.rs:17:19: 17:41 note: expansion site
main.rs:22:6: 22:6 note: previous borrow ends here
main.rs:16     pub fn safe_write_to_slot(&mut self, elem : uint) -> Result<(), &str> {
/main.rs:22     }
               ^
main.rs:37:9: 37:29 error: cannot assign to immutable dereference (dereference is implicit, due to indexing)
main.rs:37         self.elems[elem] = 1;
                   ^~~~~~~~~~~~~~~~~~~~
error: aborting due to 2 previous errors
Could not compile `borrow`.

To learn more, run the command again with --verbose.

【问题讨论】:

    标签: rust


    【解决方案1】:

    生命周期推断导致了这里的问题。

    get_slot 方法被解释为:

    pub fn get_slot<'a>(&'a self) -> Result<uint, &'a str> {
    

    结果绑定到与self 相同的生命周期,这导致self 保持冻结状态,直到结果被丢弃。但是,您不想将self 的生命周期链接到&amp;str,因为您只返回字符串文字。通过将get_slotsafe_write_to_slot 中的&amp;str 更改为&amp;'static str,您将不会再收到错误,因为在调用unsafe_write_to_slot 时,self 将不再被视为借用。

    【讨论】:

    • 只是为了让我把事情弄清楚,如果我不仅在结果中返回字符串文字会发生什么?那我就不能使用静态生命周期了吧?
    • &amp;'a str 表示您返回的字符串切片至少在 self 有效时有效。这通常意味着您返回的字符串切片是self 的成员。在这种情况下,编译器不允许更改 self 以防止您意外地使之前返回的字符串切片无效。但是,如果您要返回在函数中创建的字符串,则必须改用 String
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-26
    • 1970-01-01
    • 2014-03-30
    • 2021-03-18
    相关资源
    最近更新 更多