Rust crypto::hmac::hmac::new中的参数类型不匹配

Rust crypto::hmac::hmac::new中的参数类型不匹配,rust,Rust,我正在使用并且有一些奇怪的错误: extern crate crypto; use crypto::sha2::{Sha256, Sha384, Sha512}; use crypto::hmac::Hmac; use crypto::digest::Digest; use crypto::mac::Mac; enum MyType { Type1, Type2, Type3 } //...... let mut hmac = Hmac::new(match myType {

我正在使用并且有一些奇怪的错误:

extern crate crypto;
use crypto::sha2::{Sha256, Sha384, Sha512};
use crypto::hmac::Hmac;
use crypto::digest::Digest;
use crypto::mac::Mac;


enum MyType {
  Type1,
  Type2,
  Type3
}

//......

let mut hmac = Hmac::new(match myType {
   MyType::Type1 => Sha256::new(),
   MyType::Type2 => Sha384::new(),
   MyType::Type3 => Sha512::new()
  }, my_secret.to_string().as_bytes()
);
错误是:

error: match arms have incompatible types:
 expected `crypto::sha2::Sha256`,
    found `crypto::sha2::Sha384`
(expected struct `crypto::sha2::Sha256`,
    found struct `crypto::sha2::Sha384`) [E0308]
   let mut hmac = Hmac::new(match algorithm {
       MyType::Type1 => Sha256::new(),
       MyType::Type2 => Sha384::new(),
       MyType::Type3 => Sha512::new(),
       _ => panic!()
     }, secret.to_string().as_bytes()
 note: match arm with an incompatible type
       MyType::Type2 => Sha384::new(),
                                         ^~~~~~~~~~~~~
 help: methods from traits can only be called if the trait is implemented and in scope; the following traits define a method `input`, perhaps you need to implement one of them:
 help: candidate #1: `crypto::cryptoutil::FixedBuffer`
 help: candidate #2: `crypto::digest::Digest`
 help: candidate #3: `crypto::mac::Mac`
 help: methods from traits can only be called if the trait is implemented and in scope; the following traits define a method `result`, perhaps you need to implement one of them:
 help: candidate #1: `crypto::digest::Digest`
 help: candidate #2: `crypto::mac::Mac`
为什么呢?SH256::new的类型是否与SH384::new和SH512::new的类型相同

SH256::new的类型是否与SH384::new和SH512::new的类型相同

不。如果你看源代码,它们显然是不同的类型,不管编译器告诉你它们是不同的类型

除此之外,您还试图在单个表达式中创建三种不同类型的Hmac之一,这也是不可能的。如果查看源代码中的定义,您将看到

impl <D: Digest> Hmac<D> {
    // ...
    pub fn new(mut digest: D, key: &[u8]) -> Hmac<D> {
        // ...
    }
    // ...
}

如果引用不起作用,也可以使用方框。

不。如果你看源代码,它们显然是不同的类型,而不管编译器告诉你它们是不同的类型。-它们都实现了trait摘要和Hmac::new接受摘要。他们怎么可能是不同的类型?@AlexanderSupertramp:他们实现了一个共同的特征是不相关的:他们是不同的类型。所有内置整数都实现Int,但它们仍然是不同的类型。摘要特性只是与多种不同类型交互的通用接口。@AlexanderSupertramp:不,它不是。如果您查看,您将看到它接受D:Digest,也就是说:如果D实现了Digest特性,那么它接受任意类型D。换句话说:Hmac::new可以接受实现摘要的任何单一类型,而不是所有类型。这需要动态输入,Rust没有这种功能。另外,您的陈述不仅误导了Sha256的类型:Sha256没有类型,它是一个类型。@AlexanderSupertramp:同样,不相关。每个Sha*都是不同的类型。每个Hmac都是不同的类型。他们实施或不实施什么特征并不重要。Hmac一次只能处理其中一种类型。如果这仍然没有意义,我只能建议你去重新阅读,特别是在解释单晶化的地方。@AlexanderSupertramp:不,它必须知道D的类型,它只是一个实现摘要的类型。现在也警告不要进行冗长的评论讨论;如果你还是不明白,我建议你在网上询问。
let (hmac_sha256, hmac_sha384, hmac_sha512);
let mac: &mut crypto::mac::Mac = match myType {
    MyType::Type1 => {
        hmac_sha256 = Hmac::new(Sha256::new(), my_secret.to_string().as_bytes();
        &mut hmac_sha256 as &mut crypto::mac::Mac
    },
    // ...
};