我有一个函数用来做一个int:
fn some_to_value(src: Option<&int>) -> Option<int> {
match src {
Some(x) => Some(*x),
None => None
}
}我希望它是通用的(并且仍然在调用者级别上与"int“一起使用)。如果复制T的实例,对我来说是可以的。所以我试了一下:
fn some_to_value<T>(src: Option<&T>) -> Option<T> {
match src {
Some(x) => Some(*x),
None => None
}
}我得到:
error: cannot move out of dereference of `&`-pointer
Some(x) => Some(*x),
^~我不明白为什么会失败(我是初学者)。
一些上下文:我复制了一个选项,因为我意识到,在"HashMap“上执行”查找“之后,只要返回"find”(包含对地图某一项的引用的选项)仍然有效,映射就不会变。
发布于 2014-06-28 00:57:26
Rust语言有一个很强的所有权概念,这导致了这个“移动与复制”场景(我将在这个答案中使用术语)。
共享引用&T (通常)是内存中某个T的只读视图。一个重要的属性是不允许使T失效:&T必须始终指向有效的T实例。
当您编写*x时,您试图按值将T移出,因为T是一个无界泛型,编译器必须假设最坏的情况:类型T不是Copy,因此必须移动所有权,也就是说,按值使用(也称为字节复制)不是语义副本,这意味着不能继续使用源(有关这一点的更多解释,请参阅我的链接答案)。移动所有权使来源无效..。但是源在&T中,所以使其无效是非法的!
*x适用于int,因为它是Copy,所以按值使用(也称为字节副本)与语义副本相同:&int没有失效。
发布于 2014-06-27 21:06:42
如果要允许复制T,就必须告诉编译器。
您可以将T的类型限制为Copy类型的类型。
可以通过简单复制位(即memcpy)来复制的类型。
fn some_to_value<T: Copy>(src: Option<&T>) -> Option<T> {
match src {
Some(x) => Some(*x),
None => None
}
}或者更一般地将T限制为实现Clone特性的类型:
fn some_to_value<T: Clone>(src: Option<&T>) -> Option<T> {
match src {
Some(x) => Some(x.clone()),
None => None
}
}发布于 2014-06-27 21:19:50
Some(x) => Some(*x)这段代码按值取x。在第一个函数中,x是一个int。像ints这样的原语实现了复制特性,这意味着它们在被值获取时会自动复制。不实现复制的类型将被移动。
您的泛型函数不能保证T将实现复制。如果编译器允许此编译,您将得到一个函数,该函数取消x,然后将基础数据复制或移动到output选项中。一个移动将使原来的内存位置无效!
您的泛型函数将使用Copy约束:some_to_value<T: Copy>,它保证T将实现复制。
您可能希望该函数能够处理的不仅仅是原语,所以您必须使用Clone特性。match语句也可以编写为一个map函数,它的作用完全相同。
fn some_to_value<T: Clone>(src: Option<&T>) -> Option<T> {
src.map(|num| num.clone())
}https://stackoverflow.com/questions/24460617
复制相似问题