2016-08-25 52 views
0

私は現在、Rustの借用の問題に直面しています。私はそれを解決するアイディアを持っています。しかし、私が見つけた方法は良い答えではないと私は思う。だから私はそれを解決する別の方法があるのだろうかと思っています。何かをするために追加の引数inputを取る方法、f2を、持っているS構造体のメンバを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(); 
} 

構造:

は、私は私の状況を記述するために、次のコード例を使用しています。もう1つの方法f1があり、f2val構造の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が関数呼び出しのために借用されているため、コピーを作成することはできません。その前に値をコピーしない限り、そのような呼び出しを行うことはできません。これは構文の制限ではなく、借用チェッカーの実施です。とにかく、実際に起こる順序でコピーと呼び出しを書く方が良いです。

引数として使用しようとしているタイプが(例:String)でない場合は、コンパイラに明示的にコピーを依頼するにはlet v = self.val.clone(); self.f2(v);と記述する必要があります。そのような呼び出しをコピーせずに行うことは許可されていません。おそらく、メソッドを変更不可能にするか、何らかの理由で引数を削除する必要があります。

+0

あなたの答えをありがとう。私は 'f2'に渡す前に' self.val'をコピーするほうがいいと思います。 –

1

あなたはコピー可能な値のために、このトリックを使用することができます。

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

しかし、明示的な一時的な変数を使用することで、より明確で慣用的です。

+0

あなたの答えをありがとう。興味深い方法。 –

関連する問題