2017-06-09 13 views
6

私はそれに任意の型を持つ配列に取り、配列の最後の要素を返す関数を書きたいので、私が試した:`&T`を` T`に変換するにはどうしたらいいですか?

fn main() { 
    let v = ["a", "b"]; 
    println!("{}", last(&v)); 
} 

fn last<T: Clone>(slice: &[T]) -> &T { 
    &slice[slice.len()-1] 
} 

、それが動作しているようですが、私は適用されたときに小さな調整:

fn main() { 
    let v = ["a", "b"]; 
    println!("{}", last(&v)); 
} 

fn last<T: Clone>(slice: &[T]) -> T { 
    &slice[slice.len()-1] 
} 

は、それから私はと会ったよ:

error[E0308]: mismatched types 
--> <anon>:9:5 
    | 
9 |  &slice[n-1] 
    |  ^^^^^^^^^^^ expected type parameter, found &T 
    | 
= note: expected type `T` 
      found type `&T` 

私はちょうどT&Tを変換する方法を教えてください。

+2

場合によっては、スライスの[メソッド 'last'](https://doc.rust-lang.org/stable/std/primitive.slice.html#method.last)があります。 – red75prime

答えて

8

あなたの最初の例では、あなたが&Tを返すと、何かを参照するので、値とタイプが一致する取っている:

fn last<T: Clone>(slice: &[T]) -> &T { 
//        ^^ 
    &slice[slice.len()-1] 
//^
} 

をしかし、その後、あなたが参照を返すつもりはないと述べましたもはやですが、実装は変更されていません

fn last<T: Clone>(slice: &[T]) -> T { 
//        ^
    &slice[slice.len()-1] 
//^
} 

T&T&mut T全て互いに異なる種類があります!これは、この "小さな調整" と同じです意味:

fn foo() -> i32 { 42 } // Before 
fn foo() -> bool { 42 } // After 

はのは、身体から&をドロップしてみましょう:

fn last<T: Clone>(slice: &[T]) -> T { 
    slice[slice.len()-1] 
} 

おっと...

error[E0507]: cannot move out of indexed content 
--> src/main.rs:4:9 
    | 
4 |   slice[slice.len()-1] 
    |   ^^^^^^^^^^^^^^^^^^^^ cannot move out of indexed content 

これはよくで説明されていますWhat does "cannot move out of indexed content" mean?


あなたの質問に対する答えは、正しい方法はありません。 3つの大きな可能性があります。

  1. はタイプがCopyを実装し、コンパイラが自動的にあなたのためにそれを逆参照:タイプがCloneを実装

    fn last_copy<T: Copy>(slice: &[T]) -> T { 
        slice[slice.len()-1] 
    } 
    
  2. ので、明示的に複製するCloneを呼び出すことができます。

    fn last_clone<T: Clone>(slice: &[T]) -> T { 
        slice[slice.len()-1].clone() 
    } 
    

    あなたのタイプに類似した方法が他にもあるかもしれません。

  3. あなたではありません。参照がある場合は、対応する値を取得できません。そのような場合は、デザインを再評価する必要があります。

関連する問題