Rust中的以下代码编译正常:
pub fn insertion_sort(data : &mut [int]){
let n = data.len();
for j in range(1, n){
let key = data[j];
// we insert data[j] into the sorted sequence
//data[0...j-1]
let mut i = j -1;
while data[i] > key{
data[i + 1] = data[i];
if i == 0{
break;
}
i -= 1;
}
data[i] = key;
}
}
Run Code Online (Sandbox Code Playgroud)
但是那一刻,我介绍了泛型如下:
pub fn insertion_sort<T : Ord>(data : &mut [T]){
let n = data.len();
for j in range(1, n){
let key = data[j];
// we insert data[j] into the sorted sequence
//data[0...j-1]
let mut i = j -1;
while data[i] > key{
data[i + 1] = data[i];
if i == 0{
break;
}
i -= 1;
}
data[i] = key;
}
}
Run Code Online (Sandbox Code Playgroud)
编译器报告以下问题:
错误:无法移出
&mut-pointer insertion.rs:6 的取消引用,让key = data [j];错误:无法移出
&mut-pointer insertion.rs:11 data [i + 1] = data [i];
从内置类型的非通用代码转换为通用代码时,我们是否需要特别小心?错误消息听起来很神秘.
[编辑]
根据弗拉基米尔的建议,我试图提出一个适用于T的版本:Ord使用切片的交换功能
pub fn insertion_sort<T : Ord>(data : &mut [T]){
let n = data.len();
for j in range(1, n){
// we insert data[j] into the sorted sequence
//data[0...j-1]
let mut i = j -1;
while data[i] > data[i+1]{
data.swap(i + 1, i);
if i == 0{
break;
}
i -= 1;
}
}
}
Run Code Online (Sandbox Code Playgroud)
是的,您需要特别小心,因为在您使用的原始代码片段中int,它是隐式可复制的(实现Copy特征),而在第二部分中,您只使用了带有Ord绑定的泛型参数.默认情况下,Rust中的值被移动而不是复制,这确实会对您可以对值执行的操作带来一些限制.如果您编写<T: Ord+Copy>而不仅仅是<T: Ord>- 您的代码将再次开始编译,您可以观察到这一点.然而,这不是一个合适的通用解决方案,因为很多类型都不是Copy.
首先,您应该阅读正式的Rust指南,其中解释了所有其他所有权和借用,核心Rust概念,为了有效地使用Rust,绝对需要理解这些概念.您看到的错误是这些概念的结果.基本上,如果您对某些数据结构有参考,则无法将任何内容移出此结构.Slice是对连续数据块的引用; 因为您没有指定Copy绑定T,Rust无法复制切片中的值,也无法移动这些值,因为禁止从引用后面移动.所以它会发出错误.
这种行为听起来有限制性,有时也是如此.很多在其他语言中很自然地完成的事情(主要是在C语言中)不能直接在Rust中完成.作为回报,Rust提供了巨大的安全保障.但是,有时您需要编写一些本身安全的东西,但这种安全性对于编译器来说并不明显.当您实现基本数据结构和算法(如排序)时,通常会发生这种情况.unsafe当然,最终的工具是块,但在这种情况下你不需要它们.Rust在std::mem模块中提供了几个非常有用的功能,特别是swap()和replace().但是,特别是对于切片,有一种swap()直接在切片上调用的方法.它以给定的指数交换元素.如果根据交换操作重新配置插入排序,您将能够编写完全通用的代码,Ord即使它们不可复制也适用于所有类型.我强烈建议您尝试这样做,因为这有助于您了解如何编写低级Rust程序.
另一方面,如果您事先知道只使用原始类型int,那么您可以放心地Copy绑定T并保留代码.或者您可以使用更通用的Clone绑定,但是clone()当您从切片中提取值时,您需要调用方法:
pub fn insertion_sort<T: Ord+Clone>(data: &mut [T]) {
let n = data.len();
for j in range(1, n) {
let key = data[j].clone();
// we insert data[j] into the sorted sequence
//data[0...j-1]
let mut i = j -1;
while data[i] > key {
data[i + 1] = data[i].clone();
if i == 0 {
break;
}
i -= 1;
}
data[i] = key;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
318 次 |
| 最近记录: |