如何从前导元素和数组中制作切片?

How to make a slice from a leading element and an array?

提问人:fadedbee 提问时间:11/17/2023 更新时间:11/17/2023 访问量:45

问:

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

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

数组 Rust Slice

评论

2赞 Jmb 11/17/2023
好吧,你可以用 和 替换,但仅此而已。id_bytes.iter()).map(|x| *x)id_bytes.into_iter()[0x02].iter()iter::once (0x02)
3赞 Sam 11/17/2023
切片 impl 因此您可以执行此操作: .Concat[&[0x02], &id_bytes[..]].concat();
0赞 user4815162342 11/17/2023
板条箱允许taplet serialised_pkey: = vec![0x02].tap_mut(|v| v.extend(id_bytes));

答:

2赞 drewtato 11/17/2023 #1

首先,有一个较短的版本:.但是,有一些方法可以完全避免迭代器。.map(|x| *x).copied()

由于您知道数组的长度为 32,因此可以使用长度为 33 的数组来避免分配 a。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);

如果您可以控制 ,则可以编写一个构造函数,该构造函数采用 Read 的实现者。这更灵活,因为它不需要所有字节都位于一个切片中。在处理 的序列时,请考虑使用 和 特征。PublicKeyReadWriteu8

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

评论

1赞 fadedbee 11/18/2023
感谢您的帮助。我通过声明数组最初充满0x02来保存一行。let mut serialised_pkey = [0x02; 33]; serialised_pkey[1..].copy_from_slice(&id_bytes);