我想从toml配置文件加载 nonce
. 在 pub fn get_nonce()
中检索 nonce
. 我想将结果实例化为lazy_static宏类型 HarshBuilder
的 salt
.
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 回答
Option<Vec<u8>>
是一个红色的鲱鱼,重要的是salt()
的原型,正如你在salt
的定义中看到的:它期望一个满足特征
Into<Vec<u8>>
的参数 . 从documentation您可以看到Into<T>
的这些通用实现:From<T>
forU
暗示Into<U>
forT
Into
是自反的,这意味着实现了Into<T>
forT
.所以你可以传递给
salt
:类型为
Vec<u8>
的值 .如果为
Vec<u8>
实现了From<T>
,则为T
类型的值 .直接实现
Into<Vec<u8>>
的值 .现在,您有一个
Result<Vec<u8>, ConfigError>
类型的值,它不满足上述任何一个 . 这就是所有这些错误消息试图告诉你的 .简单的解决方案是将您的功能更改为:
如果您无法更改该返回类型,则可以使用
unwrap()
从Result()
获取实际值(并在出错时崩溃):如果
get_nonce()
函数确实失败了,那么你必须正确地管理错误,也许你的MASK
值为Result<Harsh, ConfigError>
?由于
get_nonce
函数返回Result
,因此需要处理可能的错误 . 您可以通过以下三种方式修复代码:鉴于
get_nonce
永远不会返回错误,您只需更改它,使其直接返回nonce
而不是Ok(nonce)
.或者您可以在结果上调用
unwrap
以访问内部的Vec<u8>
(如果稍后更改get_nonce
以生成错误,则会崩溃) .或者您可以添加适当的错误处理(摆脱
unwrap
并使用try!
或?
运算符传播错误并在某些顶级点正确捕获它们) .