2017-06-09 59 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. 不要。有时,如果您有参考,则无法获得相应的值。在这些情况下,您需要重新评估您的设计。