是否可以在可变引用(&mut E<T>
)的值中切换变量,而无需对T
附加限制,也可以不求助于不安全的代码?
也就是说,给定一个枚举:
enum E<T> {
VariantA(T),
VariantB(T)
}
编写此内容的正确方法是什么:
let x: E<???> = E::VariantA(??);
change_to_variant_b(&mut x);
assert_eq!(x, E::VariantB(??));
最佳答案
我要在这里转弯说不。
但是,只需对签名进行少量更改,就可以实现:
fn change_to_variant_b<T>(e: E<T>) -> E<T> {
match e {
E::VariantA(t) => E::VariantB(t),
E::VariantB(t) => E::VariantB(t),
}
}
可以使用
unsafe
:fn change_to_variant_b<T>(e: &mut E<T>) {
use std::ptr;
unsafe {
match ptr::read(e as *const _) {
E::VariantA(t) => ptr::write(e as *mut _, E::VariantB(t)),
E::VariantB(t) => ptr::write(e as *mut _, E::VariantB(t)),
}
}
}
可能有其他界限(
Default
或Clone
):fn change_to_variant_b<T: Default>(e: &mut E<T>) {
match std::mem::replace(e, E::VariantA(T::default())) {
E::VariantA(t) => e = E::VariantB(t),
E::VariantB(t) => e = E::VariantB(t),
}
}