sha256 crate中digest传&Vec<u8>报错,&*Vec<u8>可行的原因?
问题
使用sha256 crate生成SHA256哈希值时,已弃用的digest_bytes函数传入&bytes可正常运行,但官方推荐的新函数digest直接传&bytes会编译报错。编译器建议用&*bytes作为参数就能正常运行,想知道其中原理。
代码示例
fn main() { let bytes: Vec<u8> = std::fs::read("./Cargo.toml").unwrap(); let hash: String = sha256::digest_bytes(&bytes); // 已弃用但可用 // let hash: String = sha256::digest(&bytes); // 无法运行 // let hash: String = sha256::digest(&*bytes); // 可运行,但原因不明 println!("{}", hash); }
报错信息
--> src/main.rs:3:31 | 3 | let hash = sha256::digest(&bytes); | -------------- ^^^^^^ the trait `Sha256Digest` is not implemented for `&Vec<u8>` | | | required by a bound introduced by this call | note: required by a bound in `sha256::digest` --> /usr/local/cargo/registry/src/index.crates.io-6f17d22bba15001f/sha256-1.1.4/src/lib.rs:48:18 | 48 | pub fn digest<D: Sha256Digest>(input: D) -> String { | ^^^^^^^^^^^^ required by this bound in `digest` help: consider dereferencing here | 3 | let hash = sha256::digest(&*bytes); | +
原理解释
新旧函数的参数要求差异
- 旧函数
digest_bytes的参数类型是&[u8],由于Vec<u8>实现了Deref<Target=[u8]>,编译器会自动把&Vec<u8>(也就是你传的&bytes)隐式转换为&[u8],所以能正常调用。 - 新函数
digest是泛型函数,要求参数必须实现Sha256Digesttrait。这个trait只为[u8]、&[u8]实现了,没有为&Vec<u8>实现,所以直接传&bytes会报错。
- 旧函数
&*bytes的作用拆解bytes是Vec<u8>类型,*bytes会借助Deref特性,把Vec<u8>解引用成内部的切片[u8]。- 再对这个切片取引用,
&*bytes就得到了&[u8]类型,而&[u8]正好实现了Sha256Digesttrait,符合digest函数的参数要求,因此可以正常运行。
替代写法
你也可以用&bytes[..]来代替&*bytes,两者效果完全一致,都是获取Vec<u8>的切片引用&[u8]。
内容的提问来源于stack exchange,提问作者guenhter
相关产品推荐
相关产品推荐

