[英]Templating input and output type in rust with bitvec
Here I have two functions in rust which convert a bitvec into an integer.在这里,我在 rust 中有两个函数,它们将 bitvec 转换为 integer。 They are identical except for their types, so I'd like to template over both:除了它们的类型外,它们是相同的,所以我想对两者进行模板化:
BitVec
and BitSlice
输入类型BitVec
和BitSlice
u32
or u64
返回类型u64
或u32
use bitvec::prelude::*; // bitvec = "0.22.3"
fn bslice_to_int(bv: &BitSlice::<Lsb0, u8>) -> u32 {
let mut int = 0;
for bit in bv {
int = int << 1;
if bit == true {
int += 1;
}
}
return int;
}
fn bv_to_int(bv: &BitVec::<Lsb0, u8>) -> u64 {
let mut int = 0;
for bit in bv {
int = int << 1;
if bit == true {
int += 1;
}
}
return int;
}
fn main() {
let bits = bitvec![Lsb0, u8; 1,0,1,0];
let val1 = bslice_to_int(&bits[0..2]);
let val2 = bv_to_int(&bits);
println!("{} {}", val1, val2); // "10 2"
}
I seem to have a different problem with each.我似乎对每个都有不同的问题。
Trying 1) to make the input type generic:尝试 1) 使输入类型通用:
fn bv_to_int_generic_in<T>(bv: &T) -> u64 {
let mut int = 0;
for bit in bv {
int = int << 1;
if bit == true {
int += 1;
}
}
return int;
}
fn main() {
let bits = bitvec![Lsb0, u8; 1,0,1,0];
let val1 = bv_to_int_generic_in::<BitSlice::<Lsb0, u8>>(&bits[0..2]);
let val2 = bv_to_int_generic_in::<BitVec::<Lsb0, u8>>(&bits);
println!("{} {}", val1, val2);
}
doesn't compile, and gives an error that the generic T
doesn't have the Iterator
trait implemented:不编译,并给出泛型T
没有实现Iterator
trait 的错误:
error[E0277]: `&T` is not an iterator
--> src/main.rs:28:14
|
28 | for bit in bv {
| ^^ `&T` is not an iterator
|
= help: the trait `Iterator` is not implemented for `&T`
= note: required because of the requirements on the impl of `IntoIterator` for `&T`
note: required by `into_iter`
--> /Users/jlees/.rustup/toolchains/stable-x86_64-apple-darwin/lib/rustlib/src/rust/library/core/src/iter/traits/collect.rs:234:5
|
234 | fn into_iter(self) -> Self::IntoIter;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Trying 2) to make the return type generic:尝试 2) 使返回类型通用:
// Trying to template the output type
fn bv_to_int_generic_out<T>(bv: &BitVec::<Lsb0, u8>) -> T {
let mut int: T = 0;
for bit in bv {
int = int << 1;
if bit == true {
int += 1;
}
}
return int;
}
fn main() {
let bits = bitvec![Lsb0, u8; 1,0,1,0];
let val1: u32 = bv_to_int_generic_out::<u32>(&bits);
let val2: u64 = bv_to_int_generic_out::<u64>(&bits);
println!("{} {}", val1, val2);
}
also doesn't compile, and gives errors that T
is not an {integer}
:也不会编译,并给出T
不是{integer}
的错误:
error[E0308]: mismatched types
--> src/main.rs:55:20
|
54 | fn bv_to_int_generic_out<T>(bv: &BitVec::<Lsb0, u8>) -> T {
| - this type parameter
55 | let mut int: T = 0;
| - ^ expected type parameter `T`, found integer
| |
| expected due to this
|
= note: expected type parameter `T`
found type `{integer}`
error[E0369]: no implementation for `T << {integer}`
--> src/main.rs:57:15
|
57 | int = int << 1;
| --- ^^ - {integer}
| |
| T
|
help: consider restricting type parameter `T`
|
54 | fn bv_to_int_generic_out<T: std::ops::Shl<Output = {integer}>>(bv: &BitVec::<Lsb0, u8>) -> T {
| +++++++++++++++++++++++++++++++++++
error[E0368]: binary assignment operation `+=` cannot be applied to type `T`
--> src/main.rs:59:7
|
59 | int += 1;
| ---^^^^^
| |
| cannot use `+=` on type `T`
|
help: consider restricting type parameter `T`
|
54 | fn bv_to_int_generic_out<T: std::ops::AddAssign>(bv: &BitVec::<Lsb0, u8>) -> T {
| +++++++++++++++++++++
See also this gist for the above code in one place: https://gist.github.com/johnlees/49e6a7bd85b3545bba20e8670180f24a有关上述代码,另请参阅此要点: https://gist.github.com/johnlees/49e6a7bd85b3545bba20e8670180f24a
I am new to rust, and I realise that I'm trying to write these like C++ templates which may well be the wrong approach.我是 rust 的新手,我意识到我正在尝试像 C++ 模板一样编写这些模板,这很可能是错误的方法。 Any advice on the correct rust approach for making either the input or output types generic would be appreciated!任何关于正确的 rust 方法的任何建议都将不胜感激!
You can create a simple macro to declare them:您可以创建一个简单的宏来声明它们:
use bitvec::prelude::*; // bitvec = "0.22.3"
macro_rules! bitvec_to {
($func_name:ident, $input_type:ty, $output_type:ty) => {
fn $func_name(bv: &$input_type) -> $output_type {
let mut int = 0;
for bit in bv {
int = int << 1;
if bit == true {
int += 1;
}
}
return int;
}
};
}
bitvec_to!(bslice_to_int, BitSlice::<Lsb0, u8>, u32);
bitvec_to!(bv_to_int, BitVec::<Lsb0, u8>, u64);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.