生活有生锈的一生

时间:2014-08-31 23:43:05

标签: pointers rust lifetime

我实际上是在写一个简单的命令行程序。它应该查找命令行参数,如果没有,它应该要求用户输入所需的参数。这是我的代码:

fn main() {
    let mut reader = io::stdin();
    let args = os::args();
    let mut input: &str;
    if args.len() < 2 {
        println!("Please enter a number:");
        input = reader.read_line().ok().expect("Failed to read line").as_slice().trim();
    } else {
        input = args.get(1).as_slice();
    }

    let opt: Option<int> = from_str(input);
    let num: int = match opt{
        Some(number) => number,
        None         => 1
    };
}

我知道read_line()的结果只有调用它的块的生命周期,因此程序无法编译。但我没有看到任何其他方法来解决这个问题。

Rust是我的第一个系统编程语言,我认为我仍然没有真正理解指针,特别是~&之间的区别,所以也许有一个解决方案使用指针,由于我对指针缺乏了解,我看不到它。

感谢您的帮助!

纳斯

2 个答案:

答案 0 :(得分:2)

在您的情况下,问题来自于您在input中存储的内容是&str,也就是说,字符串的切片。

在Rust中,切片是像时尚一样的数组内容(数组,向量,字符串...)的视图,实际上是对第一个知道长度的元素的引用数据,但它没有任何东西。

当你理解底层String在块结束时被销毁时,你就是这样,在完成之后,你的input将引用已被释放的内存,这是不允许的由鲁斯特。您需要一份数据副本,因为根据您对数据的处理,您无法获得数据的所有权。

您可以让input类型为String而不是&str,这样它就会拥有自己的数据。您需要进行一些更改,例如:

input = String::from_str(/* your old code */);

let opt: Option<int> = from_str(input.as_slice());

答案 1 :(得分:2)

免责声明:我也是一个新手,到目前为止仅用了两周的Rust ......

使用另一个String缓冲区

您可以将短期String的有效期延长到另一个mut String,从而有效延长其寿命:

use std::{io, os};

fn main() {
    let mut reader = io::stdin();
    let args = os::args();
    let mut save : String;
    let input: &str = if args.len() < 2 {
        println!("Please enter a number:");
        save = reader.read_line().ok().expect("Failed to read line");
        save.as_slice().trim()
    } else {
        args[1].as_slice()
    };

    let opt: Option<int> = from_str(input);
    let num: int = match opt{
        Some(number) => number,
        None         => 1
    };
    println!("num=={}", num);
}

这有点难看,但效率最高(谁在乎......?)

只需到处使用String

由@Levans

提出
use std::{io, os};

fn main() {
    let mut reader = io::stdin();
    let args = os::args();
    let input: String = if args.len() < 2 {
        println!("Please enter a number:");
        String::from_str(reader.read_line().ok().expect("Failed to read line").as_slice().trim())
    } else {
        args[1].clone()
    };

    let opt: Option<int> = from_str(input.as_slice());
    let num: int = match opt{
        Some(number) => number,
        None         => 1
    };
    println!("num=={}", num);
}

args[1].clone()类型为args[1]时,我觉得String有点违反直觉。但是否则我们最终会将String移出不可变的String向量args

关于.ok().expect(...)

的说明

您可以找到方便小程序的unwrap()方法