gpt4 book ai didi

rust - 我如何在编译时检查切片是否具有特定大小?

转载 作者:行者123 更新时间:2023-12-02 16:12:08 25 4
gpt4 key购买 nike

我想在编译时检查 From 中使用的切片实现是一个特定的大小。

( Playground )

#[derive(Debug)]
struct Pixel {
r: u8,
g: u8,
b: u8,
}

impl From<&[u8]> for Pixel {
fn from(arr: &[u8]) -> Pixel {
Pixel {
r: arr[0],
g: arr[1],
b: arr[2],
}
}
}

fn main() {
println!("Hello, world!");

let arr: [u8; 9] = [1, 2, 3, 4, 5, 6, 7, 8, 9];
let pixels: Vec<Pixel> = arr.chunks_exact(3).map(Pixel::from).collect();
println!("{:.?}", pixels);
}

这并没有我想要的那么具体。我想查看 arr传递给 Pixel::from<&[u8]>()尽可能清楚地是 3 个元素(在编译时)。

想到assert!(arr.len()==3) ,但这会在运行时检查。

所以我想也许我可以通过 ( Playground ) 进行转换:

impl From<[u8; 3]> for Pixel {
fn from(arr: [u8; 3]) -> Pixel {
Pixel {
r: arr[0],
g: arr[1],
b: arr[2],
}
}
}

但这会导致:

error[E0277]: the trait bound `Pixel: From<&[u8]>` is not satisfied
--> src/main.rs:22:30
|
22 | let pixels: Vec<Pixel> = arr.chunks_exact(3).map(Pixel::from).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<&[u8]>` is not implemented for `Pixel`
|
= help: the following implementations were found:
<Pixel as From<[u8; 3]>>

error[E0277]: the trait bound `Pixel: From<&[u8]>` is not satisfied
--> src/main.rs:22:54
|
22 | let pixels: Vec<Pixel> = arr.chunks_exact(3).map(Pixel::from).collect();
| ^^^^^^^^^^^ the trait `From<&[u8]>` is not implemented for `Pixel`
|
= help: the following implementations were found:
<Pixel as From<[u8; 3]>>
= note: required by `from`

error[E0277]: the trait bound `Pixel: From<&[u8]>` is not satisfied
--> src/main.rs:22:30
|
22 | let pixels: Vec<Pixel> = arr.chunks_exact(3).map(Pixel::from).collect();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `From<&[u8]>` is not implemented for `Pixel`
|
= help: the following implementations were found:
<Pixel as From<[u8; 3]>>

同样我试过From<&[u8; 3]>但结果相同。

有没有办法为特定大小的切片实现 from?

这不是 How to convert a slice into an array reference? 的副本由于这个问题特别涉及在没有运行时性能影响的情况下在编译时进行检查,因此它不是强制转换 &[u8]&[u8; 3]而不是简单地在编译时检查 &[u8]有 3 个元素(可以通过使用 &[u8; 3] 来完成)。上述问题的所有答案都会影响运行时间,但我相信 this answer 中的这种方法除外。 (像 this 一样应用)但这根本不检查切片的长度是否合适。这个问题不是专门关于能够使用 Pixel::from<[u8;3]>而是一般在编译时检查长度,这些答案都没有提供或与之相关。

最佳答案

您不能在编译时执行此操作,因为切片长度在编译时未知。这是切片首先存在的一个重要原因。如果在编译时知道长度,那就是一个数组。

另见:


我宁愿同时编写易错和绝对可靠的转换:

use std::array::TryFromSliceError;
use std::convert::TryFrom;

#[derive(Debug)]
struct Pixel {
r: u8,
g: u8,
b: u8,
}

impl TryFrom<&[u8]> for Pixel {
type Error = TryFromSliceError;

fn try_from(arr: &[u8]) -> Result<Self, Self::Error> {
<&[u8; 3]>::try_from(arr).map(Self::from)
}
}

impl From<&[u8; 3]> for Pixel {
fn from(arr: &[u8; 3]) -> Self {
Self::from(*arr)
}
}

impl From<[u8; 3]> for Pixel {
fn from(arr: [u8; 3]) -> Self {
Pixel {
r: arr[0],
g: arr[1],
b: arr[2],
}
}
}

然后您可以从数组转换,允许编译时错误,或者当您有一个切片但在编译时不知道长度时,您可以尝试转换并出现运行时错误。

以后你可以使用像slice::array_chunks这样的方法将切片转换为数组的迭代器。但是,仍然您必须以某种方式处理切片的长度不正确(太长或太短)的情况。

关于rust - 我如何在编译时检查切片是否具有特定大小?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67710181/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com