首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在借用泛型类型时不能移出借用的内容

在借用泛型类型时不能移出借用的内容
EN

Stack Overflow用户
提问于 2015-02-18 22:20:15
回答 1查看 960关注 0票数 5

我有一个或多或少看起来像这样的程序

代码语言:javascript
复制
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);
}

基本上,我们在struct Test上调用一个方法,该方法借用了一些值。然后,我们在相同的结构上调用另一个方法,传递先前获得的值。

这个例子非常好用。现在,当我们使main的内容变得通用时,它就不再起作用了。

代码语言:javascript
复制
fn generic_main<T>(t: Test<T>) {
    let x = t.get_first();
    t.do_something_with_x(*x);
}

然后,我得到以下错误:

错误:不能移出借来的内容 src/main.rs:14设raw_x = *x;

我不太清楚为什么会发生这种事。有人能向我解释为什么Test<i32>在调用get_first时没有被借用,而Test<T>是借用的吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-02-18 23:16:51

简单地说,i32实现了Copy特性,但是T没有。如果您使用fn generic_main<T: Copy>(t: Test<T>),那么您当前的问题就解决了。

更长的答案是,Copy是一种特殊的特性,它意味着可以通过简单地复制位来复制值。像i32这样的类型实现Copy。像String这样的类型不实现Copy,因为例如,它需要堆分配。如果仅通过复制位来复制String,则最终将得到指向同一内存块的两个String值。那不太好(不安全!)

因此,给T一个Copy约束是非常有限制的。限制较小的限制将是T: CloneClone特性类似于Copy (在复制值方面),但它通常不仅仅是“复制位”。例如,String类型将通过为底层内存创建新的堆分配来实现Clone

这要求您更改编写generic_main的方式:

代码语言:javascript
复制
fn generic_main<T: Clone>(t: Test<T>) {
    let x = t.get_first();
    t.do_something_with_x(x.clone());
}

或者,如果您不希望具有CloneCopy边界,则可以更改do_something_with_x方法以获取对T的引用,而不是对拥有的T的引用

代码语言:javascript
复制
impl<T> Test<T> {
    // other methods elided

    fn do_something_with_x(&self, x: &T) {
        // Irrelevant
    }
}

而且你的generic_main基本上是一样的,除了你没有取消引用x

代码语言:javascript
复制
fn generic_main<T>(t: Test<T>) {
    let x = t.get_first();
    t.do_something_with_x(x);
}

您可以阅读更多关于Copy 在医生里的内容。有一些很好的例子,包括如何为您自己的类型实现Copy

票数 10
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28595075

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档