Error handling 从for循环返回结果,如果没有结果,则不返回任何结果

Error handling 从for循环返回结果,如果没有结果,则不返回任何结果,error-handling,rust,Error Handling,Rust,我想从循环的中返回如下所示的结果。请帮助解决此错误的最佳方法。我尝试了模式匹配,返回None,效果很好。但是我需要返回错误 pub fn get_account(&self) -> Result<Keys, Error> { //PATH is default home directory let values = match load_json_file(PATH + "/keys.json") { Ok(accou

我想从循环的
中返回如下所示的
结果。请帮助解决此错误的最佳方法。我尝试了模式匹配,返回
None
,效果很好。但是我需要返回
错误

pub fn get_account(&self) -> Result<Keys, Error> {
    //PATH is default home directory
    let values = match load_json_file(PATH + "/keys.json") {
        Ok(account) => Ok(account),
        Err(e) => {
            return Err(Error::Invalid_Tx(
                "The sender address cannot be nil".to_owned(),
            ))
        }
    };
    let accounts: Vec<Keys> = values.unwrap();
    let sender_address = self.sender.unwrap();
    for acc in accounts {
        if acc.address == sender_address {
            return Ok(acc);
        };
    };
    Ok(())
}
pub fn get_account(&self)->结果{
//路径是默认的主目录
让值=匹配加载json文件(路径+“/keys.json”){
正常(账户)=>正常(账户),
错误(e)=>{
返回错误(错误::无效的\u Tx(
“发件人地址不能为零”。to_owned(),
))
}
};
let accounts:Vec=values.unwrap();
让发件人地址=self.sender.unwrap();
会计科目中的会计科目{
如果acc.address==发件人地址{
返回Ok(acc);
};
};
好(())
}
预期结构
命令::键::键
,找到
()
rustc(E0308)


您试图从同一函数返回两种不同的类型:

  • 第15行:
    Ok(acc)
    属于
    Result
  • 第18行:
    Ok(())
    具有类型
    Result
如果“无结果”是有效的返回值,则可以将函数签名更改为:

pub fn get_account(&self) -> Result<Option<Keys>, Error>;
并在末尾返回Err(Error::NotFound)


您还可以使用
thiserror
,对该函数进行大量整理,这是定义错误类型的常用工具:

use thiserror::Error; // thiserror = "1.0.21"

#[derive(Debug, Error)]
enum Error {
    #[error("The sender address cannot be nil")]
    InvalidTx,
    #[error("The key was not found")]
    NotFound,
}

pub fn get_account(&self) -> Result<Keys, Error> {
    let accounts: Vec<Keys> = load_json_file(PATH + "/keys.json")
        .map_err(|_| Error::InvalidTx)?;
    let sender_address = self.sender.unwrap();
    accounts
        .into_iter()
        .find(|acc| acc.address == sender_address)
        .ok_or(Error::NotFound)
}
使用此错误::错误;//此错误=“1.0.21”
#[导出(调试,错误)]
枚举错误{
#[错误(“发件人地址不能为零”)]
残疾人,
#[错误(“找不到密钥”)]
没有发现,
}
pub fn get_帐户(&self)->结果{
let accounts:Vec=load_json_文件(PATH+“/keys.json”)
.map_err(| | Error::InvalidTx)?;
让发件人地址=self.sender.unwrap();
账户
.into_iter()
.find(| acc | acc.address==发件人地址)
.ok_或(错误::NotFound)
}

这更好,因为不需要分配错误中的
字符串
s,但是如果需要显示,它们仍然可以作为静态字符串片段使用。我还完全取消了
for
循环,这使函数更短、更简洁。

因此听起来您知道需要做什么(返回一个错误,而不是
Ok(())
)。问题是什么?@JussiKukkonen:可能OP不知道最后一行
Ok(())
是一个隐式返回值,因为它缺少最后一行
,这会造成混乱,与其他更详细的
返回错误(…)
?您好,感谢重播,我想从get_返回帐户方法有结果,但get error
预期结构`commands::key::Keys`,找到了`()
@fama问题在最后一行
确定(())
,这样你就可以说你什么也不返回(在Rust中,它写为
()
值)。“nothing”不能与
类型互换,因此需要返回某种类型的
值,例如,如果类型实现
默认
trait@fama或者您可以尝试重用
Error
enum类型的某些变体,然后返回
Err(Error::Something)(…)
而不是
Ok(())
use thiserror::Error; // thiserror = "1.0.21"

#[derive(Debug, Error)]
enum Error {
    #[error("The sender address cannot be nil")]
    InvalidTx,
    #[error("The key was not found")]
    NotFound,
}

pub fn get_account(&self) -> Result<Keys, Error> {
    let accounts: Vec<Keys> = load_json_file(PATH + "/keys.json")
        .map_err(|_| Error::InvalidTx)?;
    let sender_address = self.sender.unwrap();
    accounts
        .into_iter()
        .find(|acc| acc.address == sender_address)
        .ok_or(Error::NotFound)
}