我正在尝试将Bitv转换为uint。
use std::collections::Bitv;
use std::num::Float;
fn main() {
let mut bv = Bitv::with_capacity(3,false);
bv.set(2,true); // Set bit 3
let deci = Vec::from_fn(bv.len(),|i| if bv.get(i) {
(i as f32).exp2()
} else { 0f32 }).iter()
.fold(0u, |acc, &n| acc+n as uint);
println!["{}",deci] // 4
}
有效。虽然我想知道是否有任何我不知道的库功能,或者还有其他更好的方法。
答案 0 :(得分:2)
Bitv
没有提供将其值作为uint
返回的方法,因为Bitv
可能包含的位数多于uint
。顺便说一下,uint
的大小取决于体系结构(32位系统为32位,64位系统为64位),因此除非您使用u32
或u64
,否则应该使用uint
或Bitv
真的需要一个Vec<u8>
。
Vec<bool>
提供to_bytes
和to_bools
方法,分别返回Vec<u8>
和Vec<bool>
。 to_bytes
比Bitv
更紧凑,因此当uint
已知较大时,use std::collections::Bitv;
use std::mem;
fn main() {
let mut bv = Bitv::with_capacity(3, false);
bv.set(2, true); // Set bit 3
let deci = bv.iter().enumerate().fold(
0u64,
|accum, (bit_pos, bit)| {
if bit {
assert!(bit_pos < mem::size_of_val(&accum) * 8);
accum + (1 << bit_pos)
} else {
accum
}
});
println!("{}", deci); // 4
}
应该首选(但如果知道它很大,为什么会尝试将其转换为{{1}}?)。
我们也可以使用iter
直接迭代这些位。
{{1}}
答案 1 :(得分:2)
我对您的代码进行了一些转换。
Rust 1.0
let vec: Vec<_> = (0..bv.len()).map(|i| {
if bv[i] {
1 << i
} else {
0
}}).collect();
let deci = vec.iter().fold(0, |acc, &n| acc + n);
原始
let vec = Vec::from_fn(bv.len(), |i| {
if bv.get(i) {
1u << i
} else {
0u
}});
let deci = vec.iter().fold(0u, |acc, &n| acc + n);
Rust 1.0
let deci = bv.iter()
.fold((0, 0), |(mut acc, nth), bit| {
if bit { acc += 1 << nth };
(acc, nth + 1)
}).0;
原始
let deci = bv.iter()
.fold((0u, 0u), |(mut acc, nth), bit| {
if bit { acc += 1 << nth };
(acc, nth + 1)
}).0;
Rust 1.0
let deci = bv.iter()
.enumerate()
.filter_map(|(nth, bit)| if bit { Some(1 << nth) } else { None })
.fold(0, |acc, val| acc + val);
原始
let deci = bv.iter()
.enumerate()
.filter_map(|(nth, bit)| if bit { Some(1 << nth) } else { None })
.fold(0u, |acc, val| acc + val);
理想情况下,您可以重新组织代码以使用to_bytes,但位的顺序与您的示例不同。