簡體   English   中英

使用 bitvec 在 rust 中模板化輸入和 output 類型

[英]Templating input and output type in rust with bitvec

在這里,我在 rust 中有兩個函數,它們將 bitvec 轉換為 integer。 除了它們的類型外,它們是相同的,所以我想對兩者進行模板化:

  1. 輸入類型BitVecBitSlice
  2. 返回類型u64u32
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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM