< 返回版块

freshman 发表于 2024-06-20 09:43

这里有两段代码,第一段是无法使用&'static dyn Error的情况


use std::error::Error;

use base64::{prelude::BASE64_STANDARD, DecodeError, Engine};

pub fn decrypt<'a>(secret_key: &str, ciphertext: &str) -> Result<String, Box<dyn Error>> {
    let raw = BASE64_STANDARD.decode(ciphertext)?;

    return Ok(String::from("value"));
}

第二段是无法使用Box的情况

use std::{error::Error, fmt};

#[derive(Debug)]
enum Err {
    A,
}

impl fmt::Display for Err {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        todo!()
    }
}

impl Error for Err {
    fn source(&self) -> Option<&(dyn Error + 'static)> {
        None
    }

    fn description(&self) -> &str {
        "description() is deprecated; use Display"
    }

    fn cause(&self) -> Option<&dyn Error> {
        self.source()
    }
}

fn test() -> Result<(), &'static dyn Error> {
    return Err(&Err::A);
}

fn main() {
    let _ = test();
    println!("Hello, world!");
}
  • 在第一段中如果返回值使用了Result<String, &'static dyn std::error::Error>会提示隐式转换无法为对应的特征对象;

  • 第二段如果要使用Result<(), Box<dyn Error>>作为返回值则需要将return语句改为return Err(Box::new(Err::A));但是在第一段代码的decode()方法的源码中我并没有看到DecodeErrorBox包装;

我疑惑的是Box<dyn Error>&'static dyn std::error::ErrorDrefer trait的影响下它们俩应该是一样的吧?为什么在上述两段代码中确完全不一样?

评论区

写评论
github.com/shanliu/lsys 2024-06-26 10:10

?不止Result,也适用 Option

--
👇
freshman: 是的,是我搞混了,谢谢

--
👇
amazinqc: ?操作符是语法糖,参考try!宏:

#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[deprecated(since = "1.39.0", note = "use the `?` operator instead")]
#[doc(alias = "?")]
macro_rules! r#try {
    ($expr:expr $(,)?) => {
        match $expr {
            $crate::result::Result::Ok(val) => val,
            $crate::result::Result::Err(err) => {
                return $crate::result::Result::Err($crate::convert::From::from(err));
            }
        }
    };
}

里面会调用 From 特征自动转换

作者 freshman 2024-06-25 17:26

是的,是我搞混了,谢谢

--
👇
yomiko451: 我记得负责错误类型转换的是from和into这两个trait吧,你需要有相应实现编译器才能完成从某个错误类型到trait对象的转换

作者 freshman 2024-06-25 17:26

是的,是我搞混了,谢谢

--
👇
amazinqc: ?操作符是语法糖,参考try!宏:

#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[deprecated(since = "1.39.0", note = "use the `?` operator instead")]
#[doc(alias = "?")]
macro_rules! r#try {
    ($expr:expr $(,)?) => {
        match $expr {
            $crate::result::Result::Ok(val) => val,
            $crate::result::Result::Err(err) => {
                return $crate::result::Result::Err($crate::convert::From::from(err));
            }
        }
    };
}

里面会调用 From 特征自动转换

SleepyBoy 2024-06-21 17:52

?操作符是语法糖,参考try!宏:

#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
#[deprecated(since = "1.39.0", note = "use the `?` operator instead")]
#[doc(alias = "?")]
macro_rules! r#try {
    ($expr:expr $(,)?) => {
        match $expr {
            $crate::result::Result::Ok(val) => val,
            $crate::result::Result::Err(err) => {
                return $crate::result::Result::Err($crate::convert::From::from(err));
            }
        }
    };
}

里面会调用 From 特征自动转换

yomiko451 2024-06-20 09:50

我记得负责错误类型转换的是from和into这两个trait吧,你需要有相应实现编译器才能完成从某个错误类型到trait对象的转换

1 共 5 条评论, 1 页