首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将Option<&T>转换为Option<T>

将Option<&T>转换为Option<T>
EN

Stack Overflow用户
提问于 2014-06-27 20:53:10
回答 4查看 1.2K关注 0票数 5

我有一个函数用来做一个int:

代码语言:javascript
复制
fn some_to_value(src: Option<&int>) -> Option<int> {
    match src {
        Some(x) => Some(*x),
        None => None
    }
}

我希望它是通用的(并且仍然在调用者级别上与"int“一起使用)。如果复制T的实例,对我来说是可以的。所以我试了一下:

代码语言:javascript
复制
fn some_to_value<T>(src: Option<&T>) -> Option<T> {
    match src {
        Some(x) => Some(*x),
        None => None
    }
}

我得到:

代码语言:javascript
复制
error: cannot move out of dereference of `&`-pointer
Some(x) => Some(*x),
                ^~

我不明白为什么会失败(我是初学者)。

一些上下文:我复制了一个选项,因为我意识到,在"HashMap“上执行”查找“之后,只要返回"find”(包含对地图某一项的引用的选项)仍然有效,映射就不会变。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2014-06-28 00:57:26

Rust语言有一个很强的所有权概念,这导致了这个“移动与复制”场景(我将在这个答案中使用术语)。

共享引用&T (通常)是内存中某个T的只读视图。一个重要的属性是不允许使T失效:&T必须始终指向有效的T实例。

当您编写*x时,您试图按值将T移出,因为T是一个无界泛型,编译器必须假设最坏的情况:类型T不是Copy,因此必须移动所有权,也就是说,按值使用(也称为字节复制)不是语义副本,这意味着不能继续使用源(有关这一点的更多解释,请参阅我的链接答案)。移动所有权使来源无效..。但是源在&T中,所以使其无效是非法的!

*x适用于int,因为它是Copy,所以按值使用(也称为字节副本)与语义副本相同:&int没有失效。

票数 4
EN

Stack Overflow用户

发布于 2014-06-27 21:06:42

如果要允许复制T,就必须告诉编译器。

您可以将T的类型限制为Copy类型的类型。

可以通过简单复制位(即memcpy)来复制的类型。

代码语言:javascript
复制
fn some_to_value<T: Copy>(src: Option<&T>) -> Option<T> {
    match src {
        Some(x) => Some(*x),
        None => None
    }
}

或者更一般地将T限制为实现Clone特性的类型:

代码语言:javascript
复制
fn some_to_value<T: Clone>(src: Option<&T>) -> Option<T> {
    match src {
        Some(x) => Some(x.clone()),
        None => None
    }
}
票数 2
EN

Stack Overflow用户

发布于 2014-06-27 21:19:50

代码语言:javascript
复制
Some(x) => Some(*x)

这段代码按值取x。在第一个函数中,x是一个int。像ints这样的原语实现了复制特性,这意味着它们在被值获取时会自动复制。不实现复制的类型将被移动。

您的泛型函数不能保证T将实现复制。如果编译器允许此编译,您将得到一个函数,该函数取消x,然后将基础数据复制或移动到output选项中。一个移动将使原来的内存位置无效!

您的泛型函数将使用Copy约束:some_to_value<T: Copy>,它保证T将实现复制。

您可能希望该函数能够处理的不仅仅是原语,所以您必须使用Clone特性。match语句也可以编写为一个map函数,它的作用完全相同。

代码语言:javascript
复制
fn some_to_value<T: Clone>(src: Option<&T>) -> Option<T> {
    src.map(|num| num.clone())
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24460617

复制
相关文章

相似问题

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