2017-06-09 65 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?


您的問題的答案是:沒有一個正確的方法。有三大可能:

  1. 的類型實現Copy,編譯器會自動解引用它爲您提供:

    fn last_copy<T: Copy>(slice: &[T]) -> T { 
        slice[slice.len()-1] 
    } 
    
  2. 的類型實現Clone,這樣你就可以顯式調用Clone複製它:

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

    您的類型上可能還有其他類似的方法。

  3. 不要。有時,如果您有參考,則無法獲得相應的值。在這些情況下,您需要重新評估您的設計。