2017-10-24 14 views
4

Cloneがバインドされていない限り、汎用タイプのオブジェクトへの参照を含む構造体のCloneの特性を導出すると、オブジェクトへの参照を返しますが新しいオブジェクトではないclone()メソッドを生成します。派生したclone()メソッドが参照を返すのはなぜですか?

#[derive(Clone)] 
struct A<'a, T: 'a>{ 
    ref_generic: &'a T 
} 

fn test_call<'a, T: 'a>(a: &A<'a, T>)->A<'a, T>{ 
    a.clone() 
} 

エラーが発生します:

error[E0308]: mismatched types 
    --> src/lib.rs:15:5 
    | 
14 | fn test_call<'a, T: 'a>(a: &A<'a, T>)->A<'a, T>{ 
    |          -------- expected `A<'a, T>` because of return type 
15 |  a.clone() 
    |  ^^^^^^^^^ expected struct `A`, found &A<'_, T> 
    | 
    = note: expected type `A<'a, T>` 
       found type `&A<'_, T>` 

はなぜ、このように動作導出んが

私は、コードを持っていますか?

手動で実装すると、この障害は回避できますが、不愉快です。

impl<'a, T: 'a> Clone for A<'a, T>{ 
    fn clone(&self)->Self{ 
     A{ref_generic: self.ref_generic} 
    } 
} 

答えて

5

A::clone()は呼び出していません。 &A::clone()を呼び出しています。つまり、オブジェクトではなく参照を複製しています。

引数は、より正確に(Clone::clone&selfを取るので、単一refが代わりに自動refの参照クローンへの呼び出しのために必要で、正確に一致します)が、それができると一致するため、コンパイラは、実際には、A::clone()を呼ぶことを好むだろう't。

impl <'a, T: Clone + 'a> Clone for A<'a, T> { 
    fn clone(&self) -> Self { Self { ref_generic: self.ref_generic } } 
} 

TにバインドさCloneを:自動由来Cloneは単純としてそれを実装しているため(。あなたがあなたの代わりに(*a).clone()を実行しようとすると、エラーメッセージを見て、あなたが得ることを確認することができます)です。その境界は必要ではありませんが、自動導出では依然としてそれが必要です。これはbug #26925です。

あなたtest_call機能はAの派生Clone IMPLが利用できないので、コンパイラは&Aのための1つである、それが呼び出すことができる唯一のClone IMPL、にフォールバックすることを意味し、Tにバインドされていません。

+0

これは、 'struct A <'a、T:Clone +' a>'、 'fn test_call <'a, T: 'a>'を 'fn test_call <'a、T:Clone +' a > '、あなたの例は動作します。 –

関連する問題