我有一个独特的场景,我想使用f64
作为HashMap
中的键。特别是,我知道f64
永远不会是NaN
,我可以容忍应该相等但不能相等的f64
。所以我transmute()
从f64
到u64
。但是,当我将u64
拔出HashMap
并transmute()
回到f64
时,它是一个不同的值。代码位于playground下方和上方。
use std::collections::HashMap;
fn main() {
let x = 5.0;
let y: u64 = unsafe { std::mem::transmute(x) };
let x: f64 = unsafe { std::mem::transmute(y) };
println!("y: {}, x: {}", y, x);
let mut hash = HashMap::new();
hash.insert(y, 8);
for (y, _) in &hash {
let x: f64 = unsafe { std::mem::transmute(y) };
println!("y: {}, x: {}", y, x);
}
}
我想念什么?
答案 0 :(得分:8)
当您写for (y, _) in &hash
时,y
将成为键的引用,然后您将其转换为无意义的浮点数。
如果您写for (&y, _) in &hash
或使用*y
,您将获得期望的值。
转变错误的事情就是为什么在使用transmute
时永远不要推断类型,而总是避免使用transmute
。特别是,对于此特定的转换,有安全的方法f64::to_bits
和f64::from_bits
。更加惯用的方式是使用HashMap<FloatWrapper, Value>
实现FloatWrapper
的{{1}}。