Vector 将字符串传递给'panic'时,参数的有效期不够长`

Vector 将字符串传递给'panic'时,参数的有效期不够长`,vector,rust,Vector,Rust,参数ln的寿命不够长,我似乎找不到原因。我试图使它和我给它的值成为静态输入,但这只会导致其他问题 pub fn CompileLine(ln: &str) -> std::vec::Vec<u8> { let mut out = std::vec::Vec::new(); let splitLn: Vec<&str> = ln.split_whitespace().collect(); match splitLn[0] {

参数
ln
的寿命不够长,我似乎找不到原因。我试图使它和我给它的值成为静态输入,但这只会导致其他问题

pub fn CompileLine(ln: &str) -> std::vec::Vec<u8> {
    let mut out = std::vec::Vec::new();
    let splitLn: Vec<&str> = ln.split_whitespace().collect();
    match splitLn[0] {
        "exit" => out.push(0),
        "reg" => out.push(0x1),
        "rem" => out.push(0x2),
        "set" => out.push(0x3),
        "sum" => out.push(0x4),
        "jmp" => out.push(0x5),
        _ => panic!(splitLn[0]),
    }
    return out;
}
pub fn CompileLine(ln:&str)->std::vec::vec{
让mut out=std::vec::vec::new();
让splitLn:Vec=ln.split_whitespace().collect();
匹配splitLn[0]{
“退出”=>向外推(0),
“reg”=>向外推送(0x1),
“rem”=>向外推送(0x2),
“设置”=>out.push(0x3),
“sum”=>out.push(0x4),
“jmp”=>out.push(0x5),
_=>惊慌失措!(splitLn[0]),
}
返回;
}
错误[E0495]:由于需求冲突,无法推断自动引用的适当生存期
-->src/main.rs:3:33
|
3 |让splitLn:Vec=ln.split_whitespace().collect();
|                                 ^^^^^^^^^^^^^^^^
|
注意:首先,生命周期不能超过在函数体上以1:1定义的匿名生命周期#1。。。
-->src/main.rs:1:1
|
1 |/pub fn CompileLine(ln:&str)->std::vec::vec{
2 | | let mut out=std::vec::vec::new();
3 | |让splitLn:Vec=ln.split_whitespace().collect();
4 | |匹配拆分Ln[0]{
... |
13 | |返回;
14| | }
| |_^
注意:…这样引用就不会超过借用的内容
-->src/main.rs:3:30
|
3 |让splitLn:Vec=ln.split_whitespace().collect();
|                              ^^
=注意:但是,生存期必须对静态生存期有效。。。
注意:…以便类型`&str`满足其所需的生存期限制
-->src/main.rs:11:14
|
11 |=>panic!(splitLn[0]),
|              ^^^^^^^^^^^^^^^^^^
=注意:此错误源于当前板条箱外部的宏(在夜间构建中,使用-Z外部宏反向跟踪运行以获取更多信息)

panic!
将字符串文字作为其第一个参数1。字符串文字是一个
&'static str
,但您的字符串片段不是
'static

而是将字符串作为格式化程序参数传递:

panic!("{}", split_ln[0]),
同样值得指出的是:

  • Rust中的变量和函数使用
    snake\u case
  • 没有理由将
    split_whitespace
    的结果收集到一个向量中,除非您计划在该向量上迭代两次(甚至可能不会)
  • 不要在迭代器上循环以推入
    Vec
    ,只需
    map
    collect
  • 不需要使用
    return
    ,只需将最后一个表达式作为值即可
  • 因此,
    panic!
    的第一个参数实际上可以是实现trait的任何东西。
    Any
    trait要求实现它的任何类型都必须是静态的

    pub trait Any: 'static { /* ... */ }
    

    在这一点上,同样的逻辑也适用:你正在传递一个
    &str
    ,而一个任意的
    &str
    不符合特征绑定的
    'static

    ,从技术上讲,
    panic!
    的单参数版本接受任何
    Any+Send
    的东西。当然,
    Any
    意味着
    'static
    。这意味着这意味着
    &str:'static
    ,从而导致编译器令人困惑的生命周期推断错误。
    panic!
    还接受任意值(不仅仅是字符串),但该值必须永远有效(因为可能在所有函数完成后向用户显示)。什么
    panic!(“{}”,splitLn[0])
    是否复制
    splitLn[0]
    转换为可以传递的新的
    字符串。
    ln:&str
    参数实际上不是一个字符串,它只是指向一个可能在函数完成后某个时候消失的字符串。@SebastianRedl我真的不想深入了解这些细节,因为这可能是一个新手遇到的问题我不会有经验,但现在我想我需要把它弄糊涂。
    pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&'static str, u32, u32)) -> ! { /* ... */ }
    
    pub trait Any: 'static { /* ... */ }