我想写一个函数,它接受一个包含任何类型的数组,并返回数组的最后一个元素,所以我试过:
fn main() {
let v = ["a", "b"];
println!("{}", last(&v));
}
fn last<T: Clone>(slice: &[T]) -> &T {
&slice[slice.len()-1]
}
Run Code Online (Sandbox Code Playgroud)
这似乎有效,但当我应用一个小调整时:
fn main() {
let v = ["a", "b"];
println!("{}", last(&v));
}
fn last<T: Clone>(slice: &[T]) -> T {
&slice[slice.len()-1]
}
Run Code Online (Sandbox Code Playgroud)
然后我遇到了:
error[E0308]: mismatched types
--> <anon>:9:5
|
9 | &slice[n-1]
| ^^^^^^^^^^^ expected type parameter, found &T
|
= note: expected type `T`
found type `&T`
Run Code Online (Sandbox Code Playgroud)
如何将其转换&T为刚好T?
在第一个示例中,您将返回a &T并引用某些内容,因此值和类型匹配:
fn last<T: Clone>(slice: &[T]) -> &T {
// ^^
&slice[slice.len()-1]
// ^
}
Run Code Online (Sandbox Code Playgroud)
但是,那时你说你不会再返回一个引用,但是没有改变实现.
fn last<T: Clone>(slice: &[T]) -> T {
// ^
&slice[slice.len()-1]
// ^
}
Run Code Online (Sandbox Code Playgroud)
T,&T并且&mut T彼此都是不同的类型!这意味着它与"小调整"相同:
fn foo() -> i32 { 42 } // Before
fn foo() -> bool { 42 } // After
Run Code Online (Sandbox Code Playgroud)
让我们放弃&身体:
fn last<T: Clone>(slice: &[T]) -> T {
slice[slice.len()-1]
}
Run Code Online (Sandbox Code Playgroud)
糟糕!
error[E0507]: cannot move out of indexed content
--> src/main.rs:4:9
|
4 | slice[slice.len()-1]
| ^^^^^^^^^^^^^^^^^^^^ cannot move out of indexed content
Run Code Online (Sandbox Code Playgroud)
这是很好的解释什么是"不能搬出索引内容的"呢?.
你的问题的答案是:没有一个正确的方法.有三种可能性:
类型实现Copy和编译器自动为您解除引用:
fn last_copy<T: Copy>(slice: &[T]) -> T {
slice[slice.len()-1]
}
Run Code Online (Sandbox Code Playgroud)类型实现Clone,因此您可以显式调用Clone以复制它:
fn last_clone<T: Clone>(slice: &[T]) -> T {
slice[slice.len()-1].clone()
}
Run Code Online (Sandbox Code Playgroud)
您的类型可能还有其他方法可以执行类似的操作.
你没有.有时,如果您有参考,则无法获得相应的值.在这些情况下,您需要重新评估您的设计.