LINUX.ORG.RU

Rust и декомпозиция мутабельных методов класса

 ,


0

3

Вот простой код:

struct MyStruct {
    ...
}

impl MyStruct {
    fn foo(&mut self) {
        ...
        self.bar();
        ...
    }

    fn bar(&mut self) {
        ...
    }
}

Он не собирается, потому что cannot borrow `*self` as mutable more than once at a time.

Я не хочу писать километровые функции и хочу декомпозировать метод класса на несколько подметодов, которые друг-друга вызывают, каждый из которых можно комфортно редактировать. Меня даже устроит, если эти вспомогательные методы будут private, если Rust иначе не может доказать корректность. По факту я просто хочу разбить функцию на несколько частей. При этом дробить сам класс на несколько классов я не хочу, так как оба метода работают над одними и теми же данными.

Как это делается в Rust?

★★★★★

Последнее исправление: KivApple (всего исправлений: 1)

Меня даже устроит, если эти вспомогательные методы будут private, если Rust иначе не может доказать корректность.

Нет, такого в раст нету. Правило «мутабельная ссылка только одна» распространяется на весь код, вне зависимости от доступа. Это главное правило - никакого доказательства нет, есть только глобальные ограничения.

Как это делается в Rust?

Либо портянка, либо unsafe.

anonymous
()

он не собирается

Он собирается:

fn main() {
    let mut f = MyStruct {};

    f.foo();
}

struct MyStruct {}

impl MyStruct {
    fn foo(&mut self) {
        self.bar();
    }

    fn bar(&mut self) {}
}

Так что 4.2 и проблема как раз в коде, что ты опустил.

derlafff ★★★★★
()
Ответ на: комментарий от derlafff

Скорее всего он где-то в foo берёт ссылку let r = &self.some_field. Другими словами, сознательно хочет стрелять себе в ноги.

play.rust-lang.org

numas13
()

Разбирать на методы, которые работают с разными полями.

Например


struct Foo {
  a: Vec<u32>,
  b: u32,
}

impl Foo {
  fn do_foo(_: &mut u32) {
    //..
  }
  fn do_bar(_: &mut [u32]) {
    // ..
  }
  pub fn foo(&mut self) {
    Self::do_foo(&mut self.b);
  }
  pub fn bar(&mut self) {
    Self::do_foo(&mut self.b);
    Self::do_bar(&mut self.a);
  }
}
red75prim ★★★
()
Ответ на: комментарий от derlafff

Да, уже нашёл, у меня метод вызывается в цикле обхода коллекции по итератору.

KivApple ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.