Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 在访问向量时避免可选的检查_Rust_Optional - Fatal编程技术网

Rust 在访问向量时避免可选的检查

Rust 在访问向量时避免可选的检查,rust,optional,Rust,Optional,访问Vec时如何避免可选检查 while !self.stack.is_empty() { let top_path; if let Some(top) = self.stack.last() { top_path = top.to_vec(); } else { panic!("error (but can't happen, becouse the stack can't be empty becouse of the while l

访问
Vec
时如何避免可选检查

while !self.stack.is_empty() {
    let top_path;

    if let Some(top) = self.stack.last() {
        top_path = top.to_vec();
    } else {
        panic!("error (but can't happen, becouse the stack can't be empty becouse of the while loop)");
    }

    self.stack.pop();
    self.apply_grammar(top_path);
}
有两个问题:

  • 如果让。。。声明(但我知道我不需要)
  • 我需要一个
    else死机
    ,因为没有它,
    top\u路径
    可能会被取消初始化(->错误)

  • 这是我的错误还是生锈了?

    在这种情况下,您应该使用迭代器。它同样有效(也许更有效),而且更短:

    fn main() {
        let stack = vec![1,2,3,4,5,6];
    
        // Consume the stack, pop from the beginning
        for i in stack {
            println!("{}", i);
        }
    
        let stack = vec![1,2,3,4,5,6];
    
        // Consume the stack, pop from the end
        for i in stack.into_iter().rev() {
            println!("{}", i);
        }
    
        let stack = vec![1,2,3,4,5,6];
    
        // Don't consume the stack, read from the beginning
        for i in &stack {
            println!("{}", i);
        }
    
        // Don't consume the stack, read from the end
        for i in stack.iter().rev() {
            println!("{}", i);
        }
    }
    

    在您的示例中,Rust不知道
    is_empty
    pop
    之间有任何联系,因此它必须在
    pop
    中处理故障情况。迭代器向向量公开了一个更具知识性的接口,可以避免检查是否超出引导范围。

    irc帮助我给出了以下答案:

    while let Some(top) = self.stack.pop() {
        let top_path = top.to_vec();
        let mut is_terminal = self.tree.root.is_terminal( top.to_vec() );
    
        self.apply_grammar(top_path);
    }
    
    这看起来好多了。

    你可以使用这个方法,它会像你的
    一样让你的
    感到恐慌。。。else
    表达式:

    while !self.stack.is_empty() {
        let top = self.stack.last().unwrap();
        let top_path = top.to_vec();
        self.stack.pop();
        self.apply_grammar(top_path);
    }
    

    但是在这种情况下,使用
    ,而让
    阻塞会更清楚,正如您在自己的回答中所提到的。

    如果您需要通过循环内的可变引用调用采用
    self
    stack
    的方法,则这将不起作用。@mbrubeck-sure,但您不会弹出堆栈,因此,问题中的示例将不同。在问题的示例中,如果
    self.apply\u grammar
    采用
    &mut self
    ,则
    while
    while let
    循环将起作用,但
    for
    循环将不起作用。(您可以使用
    std::mem::replace
    解决此问题)注意:如果您不知道,这称为无可辩驳的模式。