[英]Rust generics and compile time size
我有一个类似于下面的 function:
fn write( data: u8, buf: &mut dyn Write )
{
let bytes = data.to_ne_bytes();
buf.write(&bytes);
}
我想将这个 function 用于所有固定大小的类型 u8、i8、u16、i16 等,类似于 C++ 中的重载。有没有办法用 Rust 中的 generics 做到这一点?
我试过以下,但是,它不编译:
use fixed::traits::Fixed;
fn write<T: Fixed<Bytes = [u8]> + Sized>( data: T, buf: &mut dyn Write )
{
let bytes = data.to_ne_bytes();
buf.write(&bytes);
}
我收到以下错误:
error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
|
4 | let bytes = data.to_ne_bytes();
| ^^^^^ doesn't have a size known at compile-time
|
= help: the trait `Sized` is not implemented for `[u8]`
= note: all local variables must have a statically known size
= help: unsized locals are gated as an unstable feature
我也试过这样的事情:
fn write<T: Fixed<Bytes = [u8]> + Sized>( data: T, buf: &mut dyn Write )
{
let bytes:[u8; mem::size_of_val(data)] = data.to_ne_bytes();
buf.write(&bytes);
}
不幸的是,这也不起作用。 我得到这个编译错误:
error[E0435]: attempt to use a non-constant value in a constant
|
146 | fn write<T: Fixed<Bytes = [u8]> + Sized>( data: T, buf: &mut dyn Write )
| ---- this would need to be a `const`
...
149 | let bytes:[u8; mem::size_of_val(data)] = data.to_ne_bytes();
| ^^^^
编辑:
建议的副本在我的情况下不可用。 那里使用的特性不允许我拥有一个在编译时知道其大小的类型
这是一个使用自定义特征的示例:
use std::io::Write;
trait ToBytes {
type Output;
fn to_ne_bytes(self) -> Self::Output;
// TODO: maybe add to_le_bytes and/or to_be_bytes?
}
impl ToBytes for u8 {
type Output = [u8; 1];
fn to_ne_bytes(self) -> Self::Output {
[self]
}
}
impl ToBytes for u16 {
type Output = [u8; 2];
fn to_ne_bytes(self) -> Self::Output {
self.to_ne_bytes()
}
}
impl ToBytes for u32 {
type Output = [u8; 4];
fn to_ne_bytes(self) -> Self::Output {
self.to_ne_bytes()
}
}
impl ToBytes for u64 {
type Output = [u8; 8];
fn to_ne_bytes(self) -> Self::Output {
self.to_ne_bytes()
}
}
// TODO: signed integers
fn write<T>(data: T, buf: &mut dyn Write)
where
T: ToBytes,
<T as ToBytes>::Output: AsRef<[u8]>,
{
let bytes = data.to_ne_bytes();
buf.write(bytes.as_ref());
}
fn main() {
let x: u8 = 5;
let mut buf: Vec<u8> = Vec::new();
write(x, &mut buf);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.