Rust 即使函数出错,如何继续?

Rust 即使函数出错,如何继续?,rust,Rust,我正在使用reqwest和scraper编写一个简单的rust web scraper。我的代码的一部分有一个链接“next_page”,该链接可能有效,也可能无效。我想尝试访问链接,如果有错误,请打印错误并继续下一个链接。以下是我试图做的: let next_page_response=reqwest::get(next_page)。等待; 让下一页\u响应=匹配下一页\u响应{ 正常(响应)=>响应, Err(error)=>println!(“警告:获取url“{}”时出现问题\ 错误是{

我正在使用
reqwest
scraper
编写一个简单的rust web scraper。我的代码的一部分有一个链接“next_page”,该链接可能有效,也可能无效。我想尝试访问链接,如果有错误,请打印错误并继续下一个链接。以下是我试图做的:

let next_page_response=reqwest::get(next_page)。等待;
让下一页\u响应=匹配下一页\u响应{
正常(响应)=>响应,
Err(error)=>println!(“警告:获取url“{}”时出现问题\
错误是{:?}”,下一页,错误),
};
此代码被包装在一个循环中,并且
next_page
每次迭代都会更改

这不起作用,
rustc
给出错误
错误[E0308]:“匹配”臂的类型不兼容。我认为这是有意义的,在第一个臂中表达式变成
响应
,而在第二个臂中它变成
()
。但是,如果我更改
println
恐慌,代码编译

问题:

  • 如何确认错误,然后继续
  • 为什么
    会恐慌打印时工作没有

  • .

    正如您在原始帖子中提到的,问题在于两个分支的返回值不匹配。正如kmdreko提到的,
    恐慌
    可以工作,因为它的返回类型可以在任何地方使用

    因此,如果要避免恐慌,需要使每个分支的返回值匹配

    一种方法是让双臂返回
    ()
    。如果将成功响应的处理放在匹配的主体中,代码可能非常简单

    pub fn process_response(response: &Response) {
        // ...
    }
    
    for next_page in pages {
        let next_page_response = reqwest::get(next_page).await;
        match next_page_response {
            Ok(response) => process_response(response),
            Err(error) => println!("WARN: Problem getting the url '{}'. \
                 The error was {:?}", next_page, error),
        };
    }
    
    另一种方法是让双臂返回您稍后使用的
    选项。
    (在这种情况下,我认为这会使代码变得更长、更难看,但在某些情况下它是有用的)。它可能看起来像这样:

    pub fn process_response(response: &Response) {
        // ...
    }
    
    for next_page in pages {
        let next_page_response = reqwest::get(next_page).await;
        let next_page_response = match next_page_response {
            Ok(response) => Some(response),
            Err(error) => {
                 println!("WARN: Problem getting the url '{}'. \
                     The error was {:?}", next_page, error);
                 None
            }
        };
    
        if let Some(response) = next_page_response {
            process_response(response)
        }
    }
    

    正如您在原始帖子中提到的,问题在于两个分支的返回值不匹配。正如kmdreko提到的,
    恐慌
    可以工作,因为它的返回类型可以在任何地方使用

    因此,如果要避免恐慌,需要使每个分支的返回值匹配

    一种方法是让双臂返回
    ()
    。如果将成功响应的处理放在匹配的主体中,代码可能非常简单

    pub fn process_response(response: &Response) {
        // ...
    }
    
    for next_page in pages {
        let next_page_response = reqwest::get(next_page).await;
        match next_page_response {
            Ok(response) => process_response(response),
            Err(error) => println!("WARN: Problem getting the url '{}'. \
                 The error was {:?}", next_page, error),
        };
    }
    
    另一种方法是让双臂返回您稍后使用的
    选项。
    (在这种情况下,我认为这会使代码变得更长、更难看,但在某些情况下它是有用的)。它可能看起来像这样:

    pub fn process_response(response: &Response) {
        // ...
    }
    
    for next_page in pages {
        let next_page_response = reqwest::get(next_page).await;
        let next_page_response = match next_page_response {
            Ok(response) => Some(response),
            Err(error) => {
                 println!("WARN: Problem getting the url '{}'. \
                     The error was {:?}", next_page, error);
                 None
            }
        };
    
        if let Some(response) = next_page_response {
            process_response(response)
        }
    }
    

    如果出现错误,您希望下一页响应的
    值是多少?你不能不给它赋值,因为锈不是这样起作用的。变量必须有值。-太长,读不下去了恐慌劫持了正常的控制流,因此它使用从不类型来表示永远不会返回值(并且在类型系统中可分配给任何其他类型)。@SilvioMayolo我考虑过使用某种“错误”值(我来自C/C++背景…rust中是否有类似NULL或nullptr的内容?)但问题是,这样我就失去了打印发生的确切错误的机会。如果出现错误,您希望
    next\u page\u response
    的值是多少?你不能不给它赋值,因为锈不是这样起作用的。变量必须有值。-太长,读不下去了恐慌劫持了正常的控制流,因此它使用从不类型来表示永远不会返回值(并且在类型系统中可分配给任何其他类型)。@SilvioMayolo我考虑过使用某种“错误”值(我来自C/C++背景…rust中是否有类似NULL或nullptr的内容?)但问题是这样我就失去了打印发生的准确错误的机会。这些错误中有一个更像惯用的生锈样式吗?我觉得我需要把代码分成更小的函数,但是我刚刚开始学习rust,让我的代码进行编译已经做了很多工作,我甚至没有看过函数:)我会使用第一种方法,除非有其他需要第二种方法的约束。我会添加另一种选择:将其作为
    结果
    保存,而不是切换到
    选项
    ,然后执行
    如果让Err(error)=下一页响应要打印。第一种方法需要返回
    ()
    ,对吗?所以我不能返回其他内容?您的代码实际上没有包含足够的关于返回内容或希望返回内容的信息-因此我也没有在这里包含任何内容。其中一个更像惯用的rust样式吗?我觉得我需要把代码分成更小的函数,但是我刚刚开始学习rust,让我的代码进行编译已经做了很多工作,我甚至没有看过函数:)我会使用第一种方法,除非有其他需要第二种方法的约束。我会添加另一种选择:将其作为
    结果
    保存,而不是切换到
    选项
    ,然后执行
    如果让Err(error)=下一页响应要打印。第一种方法需要返回
    ()
    ,对吗?所以我不能返回其他内容?您的代码实际上没有包含足够的关于返回内容或您想要返回的内容的信息-因此我也没有在这里包含任何内容。