循环时无法移出借用的内容 [英] cannot move out of borrowed content when iterating the loop

查看:37
本文介绍了循环时无法移出借用的内容的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图从生锈的结构中获取磁场

I'm trying to get field from my structure in rust

fn check_args(command: i32, args: Vec<String>) -> Vec<Argument> {
    let arg_tbl: [ArgsTable; 5] = [
        ArgsTable { cc: 0, ac: 1, dv: "4".to_string() },
        ArgsTable { cc: 1, ac: 1, dv: "4".to_string() },
        ArgsTable { cc: 1, ac: 2, dv: "in.txt".to_string() },
        ArgsTable { cc: 4, ac: 3, dv: "1".to_string() },
        ArgsTable { cc: 6, ac: 2, dv: "out.txt".to_string() },
    ];
    let mut arguments: Vec<Argument> = Vec::new();
    if args.len() == 0 {
        for arg in arg_tbl.iter() {
            if arg.cc == command {
                arguments.push(Argument {
                    code: arg.ac,
                    value: arg.dv,
                });
            }
        }
    }
}

但出现此错误

    |
151 |                     value: arg.dv
    |                            ^^^ cannot move out of borrowed content

如何获取 arg.dv 字段?

推荐答案

尽管您已经有了答案,但我将解释问题并提供其他解决方案.我还建议阅读在Rust中有效使用迭代器.

Although you already have an answer, I will explain the problem and provide a different solution too. I also recommend reading Effectively Using Iterators In Rust.

我将从 MCVE 开始,您可以在游乐场:

I'll start with a MCVE, which you can test on the playground too:

struct ArgsTable {
    dv: String,
}

fn check_args() -> Vec<ArgsTable> {
    let arg_tbl: [ArgsTable; 2] = [
        ArgsTable {
            dv: "4".to_string(),
        },
        ArgsTable {
            dv: "out.txt".to_string(),
        },
    ];
    let mut arguments: Vec<ArgsTable> = Vec::new();
    for arg in arg_tbl.iter() {
        arguments.push(ArgsTable { dv: arg.dv });
    }
    arguments
}

fn main() {
    check_args();
    println!("Hello, world!");
}

这使用 arg_tbl.iter(),该代码将从 arg_tbl 借用. String 不实现 Copy 特性,因此无法将其复制到 arguments 中.因为它是借来的,所以也不能移动.这将导致错误消息无法移出借用的内容.由于 String 确实实现了 Clone ,因此您可以对其进行克隆以获取副本.这就是为什么在第13行添加 clone()可以解决此问题的原因.

This uses arg_tbl.iter(), which will borrow from arg_tbl. String does not implement the Copy trait, so it can't be copied into arguments. Because it is borrowed, it can also not be moved. That causes the error message cannot move out of borrowed content. Because String does implement Clone, you can clone it to get a copy. That is why adding a clone() on line 13 fixes the problem.

还可以使用不借用的迭代器来解决此问题; into_iter .但是数组的按值迭代器目前不可用.如果您使用 arg_tbl.into_iter(),则该数组将取消对切片的引用,您仍将按引用进行迭代!但是,如果将阵列更改为 Vec ,它将无需克隆即可工作:

It is also possible to fix this using an iterator which does not borrow; into_iter. But by-value iterators for arrays are not available at the moment. If you use arg_tbl.into_iter(), the array will dereference into a slice, and you will still iterate by reference! But if you change the array into a Vec, it will work without having to clone:

let arg_tbl = vec![
    ArgsTable {
        dv: "4".to_string(),
    },
    ArgsTable {
        dv: "out.txt".to_string(),
    },
];
let mut arguments: Vec<ArgsTable> = Vec::new();
for arg in arg_tbl.into_iter() {
    arguments.push(ArgsTable { dv: arg.dv });
}

您现在还可以像这样简化for循环:

You can now also simplify the for loop like this:

for arg in arg_tbl {

这篇关于循环时无法移出借用的内容的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆