Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Loops 比较列表中的所有元素并获取匹配对的可变引用_Loops_Rust_Iterator_Borrow Checker_Borrowing - Fatal编程技术网

Loops 比较列表中的所有元素并获取匹配对的可变引用

Loops 比较列表中的所有元素并获取匹配对的可变引用,loops,rust,iterator,borrow-checker,borrowing,Loops,Rust,Iterator,Borrow Checker,Borrowing,我的目标是根据一些标准将列表中的每个元素与列表中的每个其他元素进行比较。在伪代码中,类似于: for i, x in list.enumerate(): for y in list[i..]: if x.match(y): // Modify both x and y 我希望在每个匹配对中获得两个项目的可变引用。这证明是困难的。根据,获取列表中多个项目的可变引用的最佳方法是通过。我编写了一个包装函数,用于提取对列表的两个可变引用: /// Get

我的目标是根据一些标准将列表中的每个元素与列表中的每个其他元素进行比较。在伪代码中,类似于:

for i, x in list.enumerate():
    for y in list[i..]:
        if x.match(y):
            // Modify both x and y
我希望在每个匹配对中获得两个项目的可变引用。这证明是困难的。根据,获取列表中多个项目的可变引用的最佳方法是通过。我编写了一个包装函数,用于提取对列表的两个可变引用:

/// Gets two mutable references to elements i and j in list
fn get_pair<'a, T>(i: usize, j: usize, list: &'a mut [T]) -> (&'a mut T, &'a mut T) {
    let (a, b) = list.split_at_mut(j);

    let first = &mut a[i];
    let second = &mut b[0];

    (first, second)
}
相反,我保存了一对匹配的索引,然后在另一个循环中实际获取元素并对其进行处理

// Find matching pairs and push their indices
let mut matches: Vec<(usize, usize)> = Vec::new();
for (i, stuff1) in list.iter().enumerate() {
    for (j, stuff2) in list[i..].iter().enumerate() {
        if stuff1.compare(stuff2) {
            matches.push((i, j));
        }
    }
}

// Get two mutable references by indices from list
for m in matches.iter() {
    let (i, j) = m;
    let (stuff1, stuff2) = get_pair(*i, *j, list);
    do_something(stuff1, stuff2);
}
//查找匹配对并推送其索引
让mut匹配:Vec=Vec::new();
对于list.iter().enumerate()中的(i,stuff1){
对于列表[i...iter().enumerate()中的(j,stuff2){
如果是填充1.比较(填充2){
匹配。推((i,j));
}
}
}
//从列表中通过索引获取两个可变引用
对于m in matches.iter(){
设(i,j)=m;
let(stuff1,stuff2)=获取_对(*i,*j,list);
做点什么(玩偶1,玩偶2);
}
这是可行的,但似乎有点过于复杂。有没有更简单或更简单的方法来实现这一点而不违反借款规则

理想情况下,我希望修改原始循环中的匹配对,而不需要单独的循环来遍历索引


可以在上找到我当前代码的完整示例。

您可以这样做,它生成相当不错的代码:

let mut list = [1, 2, 3];
for i in 0..list.len() {
    let (a, b) = list.split_at_mut(i);
    let item_b = &mut b[0];
    for item_a in a {
        println!("{} {}", item_a, item_b);
    }
}

这里的关键是
0..len
迭代避免将
列表
锁定为只读<“代码>拆分”向借阅检查器证明两个引用不能指向同一个元素。

您阅读了吗?它解释了为什么你想要的迭代器在安全的Rust中是不可能的。我理解为什么我不能使用可变迭代器,但我想知道如何正确地处理Rust中的上述问题。链接的答案提到,这看起来可能有用。我必须看一看。尽管我感觉到一个比我现有的更好的解决方案可能会涉及不安全的代码。我认为这是一个时代错误(我应该清理这个答案),但我认为它指的是现在所谓的任何这样的迭代器实际上都是不安全的,因为它允许您获得对同一项的两个可变引用。不能构造这样的迭代器。
let mut list = [1, 2, 3];
for i in 0..list.len() {
    let (a, b) = list.split_at_mut(i);
    let item_b = &mut b[0];
    for item_a in a {
        println!("{} {}", item_a, item_b);
    }
}