rust 如何从一个前导元素和一个数组创建一个切片?

yshpjwxd  于 2023-11-19  发布在  其他
关注(0)|答案(1)|浏览(88)

这段代码看起来比实际需要的要复杂:

pub fn new(id_bytes: [u8; 32], ipv4: Ipv4Addr, port: u16) -> Result<RemotePeer, secp256k1::Error> {
    let serialised_pkey: Vec<u8> = [0x02].iter().chain(id_bytes.iter()).map(|x| *x).collect();
    Ok(RemotePeer {
        id: U256::from_le_bytes(id_bytes),
        pkey: PublicKey::from_slice(&serialised_pkey)?,
        ipv4,
        port
    })
}

字符串
我有一个公钥的最后32个字节,在创建公钥之前,我需要在它前面加上一个“0x02”。
是否有更好的替代方案:

[0x02].iter().chain(id_bytes.iter()).map(|x| *x).collect();


我特别不喜欢.map(),它的存在只是为了消除关于&u8u8不相同的错误。

mm5n2pyu

mm5n2pyu1#

首先,.map(|x| *x)有一个更短的版本:.copied()。然而,有一些方法可以完全避免迭代器。
因为你知道数组的长度是32,你可以通过使用长度为33的数组来避免分配Vec

let mut serialised_pkey = [0; 33];
serialised_pkey[0] = 0x02;
serialised_pkey[1..].copy_from_slice(&id_bytes);

字符串
如果你不知道长度,你可以使用Vec::extend_from_slice

let mut serialised_pkey = Vec::with_capacity(id_bytes.len() + 1);
serialised_pkey.push(0x02);
serialised_pkey.extend_from_slice(&id_bytes);


如果你可以控制PublicKey,你可以写一个接受Read的实现者的构造函数。这更灵活,因为它不需要所有的字节都在一个切片中。在处理u8序列时,考虑使用ReadWrite特征。

use std::io::Cursor;
let serialised_pkey = Cursor::new([0x02]).chain(Cursor::new(id_bytes));
let public_key = PublicKey::from_reader(serialised_pkey)?;

相关问题