Rust选项,实现自定义“expect”方法

时间:2015-04-05 13:08:12

标签: rust lifetime

我对Rust很新,所以我必须警告你,我不是100%肯定我在做什么。在一个rust-sfml示例中(与问题无关)我看到了这个选项模式,这显然是一个常见的模式:

let ballSoundBuffer = match SoundBuffer::new("resources/ball.wav") {
    Some(ballSoundBuffer)   => ballSoundBuffer,
    None                    => panic!("Cannot load Ball sound buffer.")
};

后来我了解了expect()函数,因此上面的内容可以替换为:

 let ballSoundBuffer = SoundBuffer::new("resources/ball.wav").expect("Cannot load Ball sound buffer.")

为了练习,我想自己实现类似于expect方法的东西,作为一个独立的方法,并想出了类似的东西:

fn checkOption<T>(obj: Option<T>, err: &str) -> T {
    match obj {
        Some(o) => return o,
        None => panic!(err)
    }
}

目标是做一些事情:

let tmp = SoundBuffer::new("resources/ball.wav");
let ballSoundBuffer = checkOption(tmp, "Cannot load Ball sound buffer.");

我正在使用泛型,因为我还希望该方法可以使用除SoundBuffer之外的其他资源(但是在加载它们时它们也使用相同的Options模式)。但是,这根本不起作用:

src/main.rs:20:24: 20:27 error: cannot infer an appropriate lifetime due to conflicting requirements
src/main.rs:20         None => panic!(err)
                                  ^~~
<std macros>:1:1: 12:62 note: in expansion of panic!
src/main.rs:20:17: 21:6 note: expansion site
src/main.rs:17:51: 22:2 note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the block at 17:50...
src/main.rs:17 fn checkOption<T>(obj: Option<T>, err: &str) -> T {
src/main.rs:18     match obj {
src/main.rs:19         Some(o) => return o,
src/main.rs:20         None => panic!(err)
src/main.rs:21     }
src/main.rs:22 }
src/main.rs:20:24: 20:27 note: ...so that expression is assignable (expected `&str`, found `&str`)
src/main.rs:20         None => panic!(err)
                                  ^~~
<std macros>:1:1: 12:62 note: in expansion of panic!
src/main.rs:20:17: 21:6 note: expansion site
note: but, the lifetime must be valid for the static lifetime...
<std macros>:3:1: 3:28 note: ...so that the type `&str` will meet its required     lifetime bounds
<std macros>:3 $ crate:: rt:: begin_unwind (
           ^~~~~~~~~~~~~~~~~~~~~~~~~~~
<std macros>:1:1: 12:62 note: in expansion of panic!
src/main.rs:20:17: 21:6 note: expansion site
error: aborting due to previous error

我不知道该如何处理:(我希望有更多知识渊博的人可以指出我的错误。

谢谢你的时间!

3 个答案:

答案 0 :(得分:3)

有多种方法可以修复您的功能:第一种方法是在'static上添加err生命周期注释:

fn checkOption<T>(obj: Option<T>, err: &'static str) -> T {
    match obj {
        Some(o) => return o,
        None => panic!(err)
    }
}

但是,这意味着您只能为&'static str使用err类型的值(即有效的字符串常量)。

第二种方法是执行expect所做的事情并致电panic!("{}", err)而不是panic!(err)

fn checkOption<T>(obj: Option<T>, err: &str) -> T {
    match obj {
        Some(o) => return o,
        None => panic!("{}", err)
    }
}

答案 1 :(得分:2)

哦,我在发帖前搜索了几个小时,当然我在发帖后5分钟发现了问题:

panic!(err)必须为panic!("{}", err)

也许是因为我很新,但错误信息非常令人困惑......

答案 2 :(得分:1)

似乎panic!需要提供给它的字符串具有静态生存期。

将您的签名更改为fn checkOption<T>(obj: Option<T>, err: &'static str) -> T编译并执行您想要的操作。