特征限制T:从<result <t,error =“”>&gt;不满意

时间:2017-09-15 03:18:25

标签: rust traits

我想从toml配置文件加载Public Function gAtr(ByVal hContext As IntPtr, ByVal reader As String) As String Dim ret As Integer Dim rs(0) As WinscardFun.SCARDREADER_STATE Console.Write(reader) 'ReDim rs(0).rgbAtr(0 To 35) 'rs(0).dwEventState = &H0 'rs(0).rgbAtr = Nothing 'rs(0).cbAtr = 0 rs(0).szReader = reader ' "\\\\?PnP?\\Notification" rs(0).dwCurrentState = SCARD_STATE_UNAWARE ret = WinscardFun.SCardGetStatusChange(hContext, 100000000, rs, 1) Console.Write("Ret=" + ret.ToString + vbCrLf) Console.Write("Reader:" + rs(0).szReader + vbCrLf) If ret = 0 And rs(0).cbAtr > 0 And rs(0).rgbAtr IsNot Nothing Then test = "Success" Else test = "Fail" End If Return test End Function 。在nonce中检索nonce。我想将结果实例化为lazy_static宏类型pub fn get_nonce()的{​​{1}}。

salt

编译器返回错误:

HarshBuilder

因此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>

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

2 个答案:

答案 0 :(得分:2)

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

  • 鉴于get_nonce永远不会返回错误,您只需更改错误即可直接返回nonce而不是Ok(nonce)
  • 或者,您可以在结果上调用unwrap来访问内部的Vec<u8>(如果您稍后更改get_nonce以生成错误,则会崩溃)。
  • 或者您可以添加适当的错误处理(摆脱unwrap并使用try!?运算符传播错误并在某些顶层正确捕获它们点)。

答案 1 :(得分: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> U隐含Into<U> T
  • Into具有反身性,这意味着Into<T>的{​​{1}}已实施。

所以你可以传递给T

  • 类型salt
  • 的值
  • 如果Vec<u8>已实施此类T,则为From<T>类型的值。
  • 直接实现Vec<u8>的值。

现在,您有一个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