2016-08-25 3 views
0

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

Я использую следующий пример кода, чтобы описать мою ситуацию:

struct S { 
    val: u8 
} 

impl S { 
    pub fn f1(&mut self) { 
     println!("F1"); 
     self.f2(self.val); 
    } 

    pub fn f2(&mut self, input: u8) { 
     println!("F2"); 

     // Do something with input 
    } 
} 

fn main() { 
    let mut s = S { 
     val: 0 
    }; 

    s.f1(); 
} 

Структура S имеет метод, f2, который принимает дополнительный аргумент input, чтобы сделать что-то. Существует еще один метод: f1, который вызывает f2 с val структуры S. Аутсайдер может называть либо f1, либо f2 для разных вариантов использования.

Когда я составил код выше, я получил следующее сообщение об ошибке:

src\main.rs:9:17: 9:25 error: cannot use `self.val` because it was mutably borrowed [E0503] 
src\main.rs:9   self.f2(self.val); 
           ^~~~~~~~ 
src\main.rs:9:9: 9:13 note: borrow of `*self` occurs here 
src\main.rs:9   self.f2(self.val); 
         ^~~~ 

Я примерно понимаю, как заимствование работает в Русте. Так что я знаю, что я могу решить эту проблему путем изменения реализации f1 в:

pub fn f1(&mut self) { 
    let v = self.val; 
    println!("F1"); 
    self.f2(v); 
} 

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

ответ

3

Ваше решение работает не из-за дополнительной привязки переменной, а из-за дополнительной копии . Целые типы могут быть неявно скопированы, поэтому let v = self.val создает копию значения. Эта копия не заимствована у self, но принадлежит. Таким образом, компилятор позволяет вам позвонить f2 с этой копией.

Если вы напишете self.f2(self.val), компилятор также попытается сделать копию self.val. Однако в этом месте невозможно сделать копию, потому что self заимствовано для вызова функции. Таким образом, невозможно выполнить такой вызов, если вы не скопируете его перед этим. И это не синтаксическое ограничение, а принудительное выполнение проверки чека. Во всяком случае, лучше написать копирование и вызов в том порядке, в котором они на самом деле происходят.

Если тип, который вы пытаетесь использовать в качестве аргумента, не был Copy (например, String), вам необходимо написать let v = self.val.clone(); self.f2(v);, чтобы запросить компилятор для копирования явно. Выполнение таких вызовов без копирования не допускается. Вероятно, вам нужно будет сделать метод не изменяемым или устранить аргумент каким-то образом.

+0

Спасибо за ваш ответ. Я думаю, что лучше скопировать 'self.val', прежде чем передать его в' f2'. –

1

Вы можете использовать этот трюк для Copyable значений:

pub fn f1(&mut self) { 
    println!("F1"); 
    match self.val {x => self.f2(x)}; 
} 

Однако, используя явную временную переменную понятнее и идиоматических.

+0

Спасибо за ваш ответ. Интересный путь. –

Смежные вопросы