Невозможно заимствовать `* self` как изменяемый более одного раза за один раз при возврате Результата, содержащего ссылку - PullRequest
0 голосов
/ 09 октября 2019

Почему следующее недопустимо и что я должен вместо этого сделать, чтобы он работал?

struct Foo;

impl Foo {
    fn mutable1(&mut self) -> Result<(), &str> {
        Ok(())
    }

    fn mutable2(&mut self) -> Result<(), &str> {
        self.mutable1()?;
        self.mutable1()?;
        Ok(())
    }
}

Этот код дает:

error[E0499]: cannot borrow `*self` as mutable more than once at a time
  --> src/lib.rs:10:9
   |
8  |     fn mutable2(&mut self) -> Result<(), &str> {
   |                 - let's call the lifetime of this reference `'1`
9  |         self.mutable1()?;
   |         ----           - returning this value requires that `*self` is borrowed for `'1`
   |         |
   |         first mutable borrow occurs here
10 |         self.mutable1()?;
   |         ^^^^ second mutable borrow occurs here

Есть много вопросов с такой же ошибкой. но я не могу использовать их для решения этой проблемы, поскольку именно наличие неявного возврата, предоставленного ?, вызывает проблему, без ? код успешно компилируется, но с предупреждениями.

Playground

1 Ответ

4 голосов
/ 09 октября 2019

Это та же проблема, что обсуждалась в Возврат ссылки из HashMap или Vec приводит к тому, что заем остается в силе за пределами области действия? . Через срок службы срок службы &str привязан к сроку &self. Компилятор не знает, что заимствование не будет использоваться при условии, что возвращается Ok. Это слишком консервативный и запрещает этот код. Это ограничение текущей реализации средства проверки заимствований.

Если вам нужно, чтобы время жизни варианта Err было привязано к времени жизни экземпляра Foo, в безопасном случае мало что можно сделать. Ржавчина. Однако в вашем случае маловероятно, что ваш &str предназначен для привязки ко времени жизни self, поэтому вы можете использовать явные времена жизни, чтобы избежать проблемы. Например, &'static str является распространенным базовым типом ошибки:

impl Foo {
    fn mutable1(&mut self) -> Result<(), &'static str> {
        Ok(())
    }

    fn mutable2(&mut self) -> Result<(), &'static str> {
        self.mutable1()?;
        self.mutable1()?;
        Ok(())
    }
}

, поскольку это наличие неявного возврата, предоставляемого ?

Не совсем, поскольку тот же код с явным возвратом имеет ту же проблему:

fn mutable2(&mut self) -> Result<(), &str> {
    if let Err(e) = self.mutable1() {
        return Err(e);
    }
    if let Err(e) = self.mutable1() {
        return Err(e);
    }
    Ok(())
}
error[E0499]: cannot borrow `*self` as mutable more than once at a time
  --> src/lib.rs:12:25
   |
8  |     fn mutable2(&mut self) -> Result<(), &str> {
   |                 - let's call the lifetime of this reference `'1`
9  |         if let Err(e) = self.mutable1() {
   |                         ---- first mutable borrow occurs here
10 |             return Err(e);
   |                    ------ returning this value requires that `*self` is borrowed for `'1`
11 |         }
12 |         if let Err(e) = self.mutable1() {
   |                         ^^^^ second mutable borrow occurs here

...