[英]Templating a function to deduce the return type stl-container from input arguments
[英]Templating input and output type in rust with bitvec
在這里,我在 rust 中有兩個函數,它們將 bitvec 轉換為 integer。 除了它們的類型外,它們是相同的,所以我想對兩者進行模板化:
BitVec
和BitSlice
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"
}
我似乎對每個都有不同的問題。
嘗試 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);
}
不編譯,並給出泛型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;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
嘗試 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);
}
也不會編譯,並給出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 {
| +++++++++++++++++++++
有關上述代碼,另請參閱此要點: https://gist.github.com/johnlees/49e6a7bd85b3545bba20e8670180f24a
我是 rust 的新手,我意識到我正在嘗試像 C++ 模板一樣編寫這些模板,這很可能是錯誤的方法。 任何關於正確的 rust 方法的任何建議都將不勝感激!
您可以創建一個簡單的宏來聲明它們:
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.