首页 文章

特征绑定T:从<Result <T,不满足错误>>

提问于
浏览
0

我想从toml配置文件加载 nonce . 在 pub fn get_nonce() 中检索 nonce . 我想将结果实例化为lazy_static宏类型 HarshBuildersalt .

use config::{Config, File, FileFormat, ConfigError};
use harsh::{Harsh, HarshBuilder};
use settings::Server;

const CFG_DEFAULT: &'static str = "conf/default";

lazy_static! {
    static ref MASK: Harsh = HarshBuilder::new()
        .length(7)
        .salt(get_nonce())
        .init()
        .expect("invalid harsh build");
}

fn conf_file() -> Config {
    let mut cfg = Config::default();
    cfg.merge(File::from_str(CFG_DEFAULT, FileFormat::Toml))
        .unwrap();

    cfg
}

pub fn get_nonce() -> Result<Vec<u8>, ConfigError> {
    let conf = conf_file();
    let search: Server = conf.get("server").unwrap();
    let nonce: Vec<u8> = search.nonce.into_bytes();

    Ok(nonce)
}

编译器返回错误:

error[E0277]: the trait bound `std::vec::Vec<u8>: std::convert::From<std::result::Result<std::vec::Vec<u8>, config::ConfigError>>` is not satisfied
--> lib.rs:40:14
|
40 |     .salt(get_nonce())
|         ^^^^ the trait 
|
`std::convert::From<std::result::Result<std::vec::Vec<u8>, config::ConfigError>>` is not implemented for `std::vec::Vec<u8>`

|
= help: the following implementations were found:
         <std::vec::Vec<u8> as std::convert::From<std::ffi::CString>>
         <std::vec::Vec<u8> as std::convert::From<std::string::String>>
         <std::vec::Vec<T> as std::convert::From<&'a mut [T]>>
         <std::vec::Vec<T> as std::convert::From<std::borrow::Cow<'a, [T]>>>
       and 5 others
= note: required because of the requirements on the impl of `std::convert::Into<std::vec::Vec<u8>>` for `std::result::Result<std::vec::Vec<u8>, config::ConfigError>`

所以 get_nonce() 返回 Result<String, ConfigError> 的枚举结果 . 这似乎不满足 salt Option<Vec<u8>> . 您在上面看到的尝试是将 Result 枚举转换为 Vec<u8> . 但是,这不能解决错误 .

以下是审核的 HarshBuilder 特质实施:

/// Note that this factory will be consumed upon initialization.
#[derive(Debug, Default)]
pub struct HarshBuilder {
    salt: Option<Vec<u8>>,
    // ...ommitted for brevity
}

impl HarshBuilder {
/// Creates a new `HarshBuilder` instance.
pub fn new() -> HarshBuilder {
    HarshBuilder {
        salt: None,
        // ...ommited for brevity
    }
}

/// Note that this salt will be converted into a `[u8]` before use, meaning
/// that multi-byte utf8 character values should be avoided.
pub fn salt<T: Into<Vec<u8>>>(mut self, salt: T) -> HarshBuilder {
    self.salt = Some(salt.into());
    self
}

特质界限和终身精神仍然是我试图包围我的头脑的主题 . 我真的可以使用一些指导 . 也许,这可能是为什么答案对我来说并不完全明显的原因 .

2 回答

  • 2

    Option<Vec<u8>> 是一个红色的鲱鱼,重要的是 salt() 的原型,正如你在 salt 的定义中看到的:

    pub fn salt<T: Into<Vec<u8>>>(mut self, salt: T)
    

    它期望一个满足特征 Into<Vec<u8>> 的参数 . 从documentation您可以看到 Into<T> 的这些通用实现:

    • From<T> for U 暗示 Into<U> for T

    • Into 是自反的,这意味着实现了 Into<T> for T .

    所以你可以传递给 salt

    • 类型为 Vec<u8> 的值 .

    • 如果为 Vec<u8> 实现了 From<T> ,则为 T 类型的值 .

    • 直接实现 Into<Vec<u8>> 的值 .

    现在,您有一个 Result<Vec<u8>, ConfigError> 类型的值,它不满足上述任何一个 . 这就是所有这些错误消息试图告诉你的 .

    简单的解决方案是将您的功能更改为:

    pub fn get_nonce() -> Vec<u8> {
         ....
         nonce
    }
    

    如果您无法更改该返回类型,则可以使用 unwrap()Result() 获取实际值(并在出错时崩溃):

    .length(7)
        .salt(get_nonce().unwrap())
        .init()
    

    如果 get_nonce() 函数确实失败了,那么你必须正确地管理错误,也许你的 MASK 值为 Result<Harsh, ConfigError>

  • 2

    由于 get_nonce 函数返回 Result ,因此需要处理可能的错误 . 您可以通过以下三种方式修复代码:

    • 鉴于 get_nonce 永远不会返回错误,您只需更改它,使其直接返回 nonce 而不是 Ok(nonce) .

    • 或者您可以在结果上调用 unwrap 以访问内部的 Vec<u8> (如果稍后更改 get_nonce 以生成错误,则会崩溃) .

    • 或者您可以添加适当的错误处理(摆脱 unwrap 并使用 try!? 运算符传播错误并在某些顶级点正确捕获它们) .

相关问题