Rust 如何从切片复制最后一个元素

Rust 如何从切片复制最后一个元素,rust,copy,slice,Rust,Copy,Slice,我是新手,正在尝试学习使用借阅检查器的惯用方法 我正在尝试编写一个简单的函数,它接受一个切片(在数据类型上是泛型的),并返回最后一个元素,这样我就可以在之后对切片进行变异。naive实现给了我一个错误: fn last_element<T>(list: &[T]) -> T { list[list.len() - 1] } fn main() { let mut slice = [1, 2, 3, 4, 5]; let x = last_ele

我是新手,正在尝试学习使用借阅检查器的惯用方法

我正在尝试编写一个简单的函数,它接受一个切片(在数据类型上是泛型的),并返回最后一个元素,这样我就可以在之后对切片进行变异。naive实现给了我一个错误:

fn last_element<T>(list: &[T]) -> T {
    list[list.len() - 1]
}

fn main() {
    let mut slice = [1, 2, 3, 4, 5];
    let x = last_element(&slice);
    println!("{}", x);

    // I want to be able to mutate slice after extracting last element
    slice[2] = 17;
}
但是我得到了
slice[2]=17的一个错误,因为分配
x
时借用了slice。我确实希望能够在调用
last\u元素
后进行变异。我发现的一个解决方法是取消引用
x
,我相信这会消耗借用:

fn last_element<T>(list: &[T]) -> &T {
    &list[list.len() - 1]
}

fn main() {
    let mut slice = [1, 2, 3, 4, 5];
    let x = *last_element(&slice);
    println!("{}", x);
    // I want to be able to mutate slice after extracting last element
    slice[2] = 17;
}
fn最后一个元素(列表:&[T])->&T{
&list[list.len()-1]
}
fn main(){
让mut切片=[1,2,3,4,5];
设x=*最后一个_元素(&slice);
println!(“{}”,x);
//我希望能够在提取最后一个元素后对切片进行变异
切片[2]=17;
}

这是实现获取切片的最后一个元素并在之后仍然对切片进行变异的最惯用的方法吗?或者,如果我写的代码很好,我以后是否应该再也不做变异呢?

如果您使用的是简单类型,例如
i32
和其他小的、固定大小的结构,这些类型通常实现
Copy
。这个特性是一个标记,它告诉编译器在可能移动值的情况下复制内存中的值。事实上,这就是错误消息所指的
非复制片
:如果元素未实现
复制
,则必须移动它们,这将使片处于无效状态,这是不允许的

如果您将函数约束为只需要
Copy
类型,那么它会很乐意为您复制这些值:

fn last_element<T: Copy>(list: &[T]) -> T {
    list[list.len() - 1]
}
克隆通常比复制更为繁重,因为它通常在Rust代码中按字段执行,而
Copy
是对原始内存的低级操作

最后一种选择是首先返回对最后一个元素的引用。然后,函数的调用方可以决定如何处理它。如果它是
复制
类型(如数字),则取消引用它将复制它:

fn last_element<T>(list: &[T]) -> &T {
    &list[list.len() - 1]
}

fn main() {
    let mut slice = [1, 2, 3, 4, 5];
    let x = *last_element(&slice);
}

如果您使用的是简单类型,例如
i32
和其他小型固定大小的结构,则这些类型通常实现
Copy
。这个特性是一个标记,它告诉编译器在可能移动值的情况下复制内存中的值。事实上,这就是错误消息所指的
非复制片
:如果元素未实现
复制
,则必须移动它们,这将使片处于无效状态,这是不允许的

如果您将函数约束为只需要
Copy
类型,那么它会很乐意为您复制这些值:

fn last_element<T: Copy>(list: &[T]) -> T {
    list[list.len() - 1]
}
克隆通常比复制更为繁重,因为它通常在Rust代码中按字段执行,而
Copy
是对原始内存的低级操作

最后一种选择是首先返回对最后一个元素的引用。然后,函数的调用方可以决定如何处理它。如果它是
复制
类型(如数字),则取消引用它将复制它:

fn last_element<T>(list: &[T]) -> &T {
    &list[list.len() - 1]
}

fn main() {
    let mut slice = [1, 2, 3, 4, 5];
    let x = *last_element(&slice);
}

谢谢你的回复!这是否意味着将复制整个切片?(如果是这样的话,是否有方法只复制最后一个元素,以防片段很长?@rampatowl否,整个片段只是通过引用传递。只是您正在按值返回元素。因此,这将确保元素将被复制而不是移动。感谢您的回复!这是否意味着将复制整个切片?(如果是这样的话,是否有方法只复制最后一个元素,以防片段很长?@rampatowl否,整个片段只是通过引用传递。只是您正在按值返回元素。因此,这将确保元素将被复制而不是移动。
let x = last_element(&slice).clone();