gpt4 book ai didi

rust - 如何从切片中复制最后一个元素

转载 作者:行者123 更新时间:2023-11-29 08:12:10 25 4
gpt4 key购买 nike

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

我正在尝试编写一个简单的函数,它接受一个切片(数据类型的通用)并返回最后一个元素,这样我就可以在之后改变切片。天真的实现给了我一个错误:

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;
}

错误是cannot move out of type[T], a non-copy slice。我看到一种解决方法是让函数返回一个引用:

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 时借用了切片。我确实希望能够在调用 last_element 后进行变异。我发现的一个解决方法是取消引用 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;
}

这是实现能够获取切片的最后一个元素并在之后仍然改变切片的目标的最惯用的方法吗?或者,如果我写的代码很好,我什至不应该在之后再做突变吗?

最佳答案

如果您使用的是简单类型,例如 i32和其他小型固定大小的结构,这些类型通常实现 Copy .这个特征是一个标记,它告诉编译器在内存中复制值,否则它们将被移动。事实上,这就是错误消息在引用 non-copy slice 时的含义。 : 如果元素没有实现 Copy然后它必须移动它们,这会使切片处于无效状态,这是不允许的。

如果您将函数限制为只期望 Copy类型,然后它会很乐意为您复制这些值:

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

如果您的元素类型可能更复杂,并且没有实现 Copy ,那么您可以将函数约束得更宽,任何实现 Clone 的类型, 然后调用 clone()在元素返回之前:

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

克隆通常比复制更重,因为它通常在 Rust 代码中以每个字段为基础实现,而 Copy是对原始内存的低级操作。

最后一个选择是首先返回对最后一个元素的引用。然后函数的调用者可以决定如何处理它。如果是 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);
}

如果元素是 Clone但不是 Copy然后,您可以显式 clone 而不是取消引用在那一点上:

let x = last_element(&slice).clone();

关于rust - 如何从切片中复制最后一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52044150/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com