在 Rust 中,什么是保持从范围内的文件读取数据的正确方法?

In Rust, what's the correct way to keep data read from a file in scope?

所以,我试过了:

log("Loading haystack.");
// total_lines read earlier
let mut the_stack = Vec::<primitive_types::U256>::with_capacity(total_lines);
if let Ok(hay) = read_lines(haystack) { // Get BufRead
  for line in hay { // Iterate over lines
    if let Ok(hash) = line {
      the_stack.push(U256::from(hash));
    }
  }
}
log(format!("Read {} hashes.", the_stack.len()));

错误是:

$ cargo build
   Compiling nsrl v0.1.0 (/my_app)
error[E0277]: the trait bound `primitive_types::U256: std::convert::From<std::string::String>` is not satisfied
  --> src/main.rs:55:24
   |
55 |         the_stack.push(U256::from(hash));
   |                        ^^^^^^^^^^ the trait `std::convert::From<std::string::String>` is not implemented for `primitive_types::U256`
   |
   = help: the following implementations were found:
             <primitive_types::U256 as std::convert::From<&'a [u8; 32]>>
             <primitive_types::U256 as std::convert::From<&'a [u8]>>
             <primitive_types::U256 as std::convert::From<&'a primitive_types::U256>>
             <primitive_types::U256 as std::convert::From<&'static str>>
           and 14 others
   = note: required by `std::convert::From::from`

如果我有一个字符串文字而不是变量 hash,则此代码有效,例如"123abc".

我认为我应该能够使用实施 std::convert::From<&'static str>,但我不明白我是如何将 hash 保持在范围内的?

我觉得我想要实现的是一个非常正常的用例:

我错过了什么?

几乎想要这样的东西,

U256::from_str(&hash)?

在名为 from_strFromStr 特征中有一个从 &str 的转换。它 returns 一个 Result<T, E> 值,因为解析字符串可能会失败。

I think I should be able to use the implementation std::convert::From<&'static str>, but I don't understand how I'm meant to keep hash in scope?

您不能将哈希保留在 'static 生命周期范围内。看起来这是一种允许您在程序中使用字符串常量的便捷方法——但它实际上只不过是 U256::from_str(&hash).unwrap().

然而……

如果你想要 SHA-1,最好的类型可能是 [u8; 20] 或者 [u32; 5]

您需要一个 base 16 解码器,类似于 base16::decode_slice。以下是实际效果:

/// Error if the hash cannot be parsed.
struct InvalidHash;

/// Type for SHA-1 hashes.
type SHA1 = [u8; 20];

fn read_hash(s: &str) -> Result<SHA1, InvalidHash> {
    let mut hash = [0; 20];
    match base16::decode_slice(s, &mut hash[..]) {
        Ok(20) => Ok(hash),
        _ => Err(InvalidHash),
    }
}