Zagnieżdżone wywołania &mut self oraz &self w metodach struktury

0

Cześć, mam oto taki problem. Mam metodę dla struktury np.pub fn calculate(&mut self) oraz prywatną metodę fn part_of_some_calc(&self) -> usize. Czyli ciało funkcji calculate, podzieliłem sobie na N prywatnych metod aby kod był ładnie poukładany i czytelny. Przykład:

impl MyStructExample
{
   pub fn calculate(&mut self)
   {
       //rob cos
       self.value = self.part_of_some_calc(); // cannot borrow `*self` as immutable because it is also borrowed as mutable
       //rob cos
   }

   fn part_of_some_calc(&self) -> usize
   {
       //obliczenia
   }
}

Problem polega na tym, że w funkcji calculate, nie mogę zawołać żadnej innej metody tej struktury bo mam typ parametru &mut self. Ręcę związane i już nigdzie głębiej nie mogę przekazać self. Problem wydaje mi się dość powszedni, natomiast nie potrafiłem znaleźć jednoznacznego rozwiązania. Czy to mój kod jest zły, niezgodny z ideą Rusta i należy go przebudowac, czy może jest na to jakiś pattern?

EDIT: Wybaczcie, problem jednak leży gdzie indziej, Sprostowanie, da się wołać prywatne metody, które mają parametr &self, gdzie metoda wywołująca ma parametr &mut self. Ehh wciąż walczę z ogarnięciem Rusta.
Bardziej kompletny przykład, gdzie mam błąd

   pub fn calculate(&mut self)
    {
        for line in &mut self.data //std::vec::Vec<std::vec::Vec<u32>> czyli dwuwymiarowy vec. /mutable borrow occurs here
        {
            for field in line
            {
                 *field = self.do_some_calculate(); //immutable borrow occurs here // gdzie fn do_some_calculate(&self)
            }
        }
    }
2

A potrzebujesz aktualnych wartości w field w trakcie do_some_calculate?

struct X {
    data: Vec<Vec<usize>>,
}

impl X {
    fn calculate(&mut self) {
        self.data = self.recalc();
    }

    fn recalc(&mut self) -> Vec<Vec<usize>> {
        self.data
            .iter()
            .map(|line| line.iter().map(|_| self.do_some_calc()).collect())
            .collect()
    }
    fn do_some_calc(&self) -> usize {
        1
    }
}

0

@Lwojtow: @hauleth Dzięki Panowie za zaangażowanie. Ogarnąłem już wcześniej ten problem. Następnym razem wkleje pełny kod, a nie będę upraszczał bo mogą być problemy z szerszym kontekstem. Obszedłem to w ten sposób, że pętla zagnieżdżona wykona operacje przygotowawcze, a następnie kolejna pętla for wykona reszte obliczeń (czyli będzie jedna &mut, bo po skończeniu pętli znika nam ta refka). Spróbuję to też przerobić na zapis z iteratorami.
To w sumie od razu dopytam czy dobrze to rozumiem. Mamy iter, iter_mut oraz into_iter. Dwa pierwsze zawsze zwrócą refki. Natomiast into_iter ma mozliwość przeniesienia value? Jak kontener np. vec<i32> nie implementuje traita Copy (czyli kopiuj value, a nie domyślnie przenoś) to into_iter przeniesie ownership. Inaczej stworzy refki jak w przypadku iter()?

1 użytkowników online, w tym zalogowanych: 0, gości: 1