Rust &引用;无法移出借用的内容“;对命令行参数求和时

Rust &引用;无法移出借用的内容“;对命令行参数求和时,rust,borrow-checker,Rust,Borrow Checker,这是我的第一个生锈程序,似乎我已经遇到了可怕的借书检查程序。:) 程序应该读取命令行中传递的参数,求和并返回结果。我无法将参数解析为整数 use std::env; fn main() { let args: Vec<String> = env::args().collect(); let sum_args: i32 = args .iter() .skip(1) .fold(0, |a, &b

这是我的第一个生锈程序,似乎我已经遇到了可怕的借书检查程序。:)

程序应该读取命令行中传递的参数,求和并返回结果。我无法将参数解析为整数

use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    let sum_args: i32 =
        args
        .iter()
        .skip(1)
        .fold(0, |a, &b| a + b.parse::<i32>().ok().expect("Not an i32!"));
    println!("{:?}", sum_args.to_string());
}
使用std::env;
fn main(){
让args:Vec=env::args().collect();
让sum_args:i32=
args
.国际热核实验堆(iter)
.skip(1)
.fold(0,| a,&b | a+b.parse::().ok().expect(“不是i32!”);
println!(“{:?}”,sum_args.to_string());
}
它失败于:

错误[E0507]:无法移出借用的内容
-->src/main.rs:9:22
|
9.折叠(0,| a,&b | a+b.parse::().ok().expect(“不是i32!”);
|                      ^-
|                      ||
||提示:为防止移动,请使用'ref b'或'ref mut b'`
|无法移出借用的内容

如何继续?

args
是一个
Vec
,而
iter
迭代器返回对字符串的引用(
&String
)。查看类型的一个技巧是尝试为单位类型赋值
()

其中有一个显示类型的错误:

错误[E0308]:类型不匹配
-->src/main.rs:5:13
|
5 | let()=args.iter().next();
|^^应为枚举'std::option::option`,找到()
|
=注意:应为'std::option::option'类型`
=注意:找到类型“()`
在闭包中,您试图自动取消引用第二个值(
|a,&b
)。如果您能够取消引用它,那么
字符串将从向量中移出,这将使向量中的内存处于不确定状态!如果我们在这之后尝试使用矢量,我们可能会导致SEGFULT,生锈是用来帮助防止的东西之一

最简单的方法是根本不去引用它(将
b
保留为
&String
):

您不需要创建字符串来打印数字:

println!("{}", sum_args);
我可能会把它写成

use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    let sum_args: i32 =
        args
        .iter()
        .skip(1)
        .map(|n| n.parse::<i32>().expect("Not an i32!"))
        .sum();
    println!("{}", sum_args);
}

Rust 1.16甚至应支持开箱即用:

use std::env;

fn main() {
    let sum: Result<_, _> = env::args().skip(1).map(|v| v.parse::<i32>()).sum();
    let sum: i32 = sum.expect("Something was not an i32!");
    println!("{}", sum);
}
使用std::env;
fn main(){
让sum:Result=env::args().skip(1).map(|v | v.parse::()).sum();
让sum:i32=sum.expect(“某些东西不是i32!”);
println!(“{}”,总和);
}

不过,向量在默认情况下不应该是不可变的吗?我以为借来的东西是把所有权传给打电话的人,然后在使用后归还。我需要重读这一部分,谢谢你的帮助!向量是不可变的,这是真的。即使向量是可变的,也不允许像这样将值移出-向量的状态仍然处于不一致的状态。这就是为什么在向量上有特定的方法来安全地删除项目。借钱并不能转移所有权,就像借朋友的车不能给你头衔一样^_^
println!("{}", sum_args);
use std::env;

fn main() {
    let args: Vec<String> = env::args().collect();
    let sum_args: i32 =
        args
        .iter()
        .skip(1)
        .map(|n| n.parse::<i32>().expect("Not an i32!"))
        .sum();
    println!("{}", sum_args);
}
use std::env;
use std::iter::{FromIterator, Sum};

struct SumCollector<T>(T);

impl<T> FromIterator<T> for SumCollector<T>
    where T: Sum
{
    fn from_iter<I>(iter: I) -> Self
        where I: IntoIterator<Item = T>
    {
        SumCollector(iter.into_iter().sum())
    }
}

fn main() {
    let sum: Result<SumCollector<i32>, _> = env::args().skip(1).map(|v| v.parse()).collect();
    let sum = sum.expect("Something was not an i32!");
    println!("{}", sum.0);
}
use std::env;

fn main() {
    let sum: Result<_, _> = env::args().skip(1).map(|v| v.parse::<i32>()).sum();
    let sum: i32 = sum.expect("Something was not an i32!");
    println!("{}", sum);
}