Pointers 借用泛型类型时无法移出借用的内容
我有一个程序或多或少是这样的Pointers 借用泛型类型时无法移出借用的内容,pointers,rust,Pointers,Rust,我有一个程序或多或少是这样的 struct Test<T> { vec: Vec<T> } impl<T> Test<T> { fn get_first(&self) -> &T { &self.vec[0] } fn do_something_with_x(&self, x: T) { // Irrelevant } } fn ma
struct Test<T> {
vec: Vec<T>
}
impl<T> Test<T> {
fn get_first(&self) -> &T {
&self.vec[0]
}
fn do_something_with_x(&self, x: T) {
// Irrelevant
}
}
fn main() {
let t = Test { vec: vec![1i32, 2, 3] };
let x = t.get_first();
t.do_something_with_x(*x);
}
然后我得到以下错误:
错误:无法移出借用的内容
src/main.rs:14让raw_x=*x
我不完全清楚为什么会发生这种情况。有人能解释一下为什么调用
get\u first
时没有借用Test
,而Test
是借用的吗?简而言之,i32
实现了Copy
特性,但t
没有。如果您使用fn generic\u main(t:Test)
,那么您眼前的问题已经解决
较长的答案是,Copy
是一种特殊的特性,这意味着可以通过简单地复制位来复制值。像i32
这样的类型实现Copy
。像String
这样的类型不实现Copy
,因为,例如,它需要堆分配。如果仅通过复制位来复制一个字符串
,则会得到指向同一内存块的两个字符串
值。那不太好(不安全!)
因此,给你的T
一个Copy
绑定是相当严格的。限制性较小的边界是T:Clone
。Clone
特性类似于Copy
(它复制值),但它通常不仅仅通过“复制位”来完成。例如,String
类型将通过为底层内存创建新的堆分配来实现Clone
这要求您更改generic\u main
的编写方式:
fn generic_main<T: Clone>(t: Test<T>) {
let x = t.get_first();
t.do_something_with_x(x.clone());
}
您的generic\u main
基本保持不变,只是没有取消引用x
:
fn generic_main<T>(t: Test<T>) {
let x = t.get_first();
t.do_something_with_x(x);
}
fn通用_main(t:测试){
设x=t,先得到_();
t、 用x(x)做某事;
}
您可以阅读有关
复制的更多信息。这里有一些很好的例子,包括如何为您自己的类型实现Copy
。使用“移动位”有点令人困惑,因为锈会随着移动位移动。也许“复制比特”会更清晰?@MatthieuM。当然更新。值得一提的是,我直接从语言参考中引用了前面的措辞:“复制,用于“普通的旧数据”类型,可以通过简单地移动位来复制。”@BurntSushi5:有趣的是,也许我们应该警告steve,在“复制”的上下文中使用“移动”有点混乱?
impl<T> Test<T> {
// other methods elided
fn do_something_with_x(&self, x: &T) {
// Irrelevant
}
}
fn generic_main<T>(t: Test<T>) {
let x = t.get_first();
t.do_something_with_x(x);
}