【问题标题】:cannot move out of borrowed content when iterating the loop迭代循环时无法移出借用的内容
【发布时间】:2016-11-29 09:30:14
【问题描述】:

我正在尝试从我的 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 字段?

【问题讨论】:

  • 请发MCVE
  • 您复制/粘贴有问题吗?特别是这一行中的i 似乎是错误的:for i in arg_tbl.iter()
  • 该死!我很愚蠢))thanx @wimh。应将其更改为 arg 。但我也像这样克隆了arg.dvarg.dv.clone(),现在它可以工作了
  • 你看过所有其他cannot move out of borrowed content 问题吗?

标签: arrays struct rust


【解决方案1】:

虽然您已经有了答案,但我会解释问题并提供不同的解决方案。我也推荐阅读Effectively Using Iterators In Rust

我将从MCVE 开始,您也可以在the playground 上进行测试:

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_tblString 没有实现Copy trait,所以它不能被复制到arguments 中。因为是借来的,所以也搬不动。这会导致错误消息cannot move out of borrowed content。因为String 确实实现了Clone,所以您可以克隆它以获取副本。这就是为什么在第 13 行添加 clone() 可以解决问题。

也可以使用不借用的迭代器来解决这个问题; into_iter。但是数组的按值迭代器目前不可用。如果你使用arg_tbl.into_iter(),数组将解引用到一个切片中,你仍然会通过引用进行迭代!但是如果你把数组改成Vec,就可以不用克隆了:

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 循环:

for arg in arg_tbl {

【讨论】:

  • 你应该使用arg_tbl.into_iter().map(|arg| ArgsTable { dv: arg.dv }).collect()而不是手动pushing到结果向量中。
猜你喜欢
  • 2018-04-04
  • 1970-01-01
  • 2015-04-20
  • 1970-01-01
  • 1970-01-01
  • 2015-03-25
  • 2015-08-02
  • 2018-09-19
  • 2017-10-15
相关资源
最近更新 更多