我有两种类型可以测试是否相等。但是,一旦我将它们包装在Option
中,各种PartialEq
实现提供的精确性就会出现在窗外。我必须使用map
或以其他方式转换它们。
例如,让我们使用&str
和String
:
fn main() {
let a = "hello";
let b = "hello".to_owned();
assert_eq!(a, b); // Just fine
let a = Some(a);
let b = Some(b);
// error: mismatched types
assert_eq!(a, b);
// error: mismatched types
assert_eq!(a, b.as_ref());
// works, but highly tied to strings or slices,
// requires me to remember which is which
assert_eq!(a, b.as_ref().map(|x| &x[..]));
}
肯定必须有更简单或更直接的方法吗?
附带问题 - 阻止Option
更广泛地实施PartialEq
的原因是什么?我猜测一致性,我的老对手。
impl<T, U> PartialEq<Option<U>> for Option<T>
where
T: PartialEq<U>,
答案 0 :(得分:2)
直到可能,我会做那样的事情:
match (&a, &b) {
(Some(a), Some(b)) => assert_eq!(a, b),
(None, None) => (),
_ => panic!("a and b not equal"),
}
macro_rules! cmp_eq_option {
($left:expr, $right:expr) => {{
match (&$left, &$right) {
(Some(left_val), Some(right_val)) => *left_val == *right_val,
(None, None) => true,
_ => false,
}
}};
}
#[macro_export]
macro_rules! assert_eq_option {
($left:expr, $right:expr) => ({
if !cmp_eq_option!($left, $right) {
panic!(r#"assertion failed: `(left == right)`
left: `{:?}`,
right: `{:?}`"#, $left, $right)
}
});
($left:expr, $right:expr,) => ({
assert_eq_option!($left, $right)
});
($left:expr, $right:expr, $($arg:tt)+) => ({
if !cmp_eq_option!($left, $right) {
panic!(r#"assertion failed: `(left == right)`
left: `{:?}`,
right: `{:?}`: {}"#, $left, $right, format_args!($($arg)+))
}
});
}
答案 1 :(得分:0)
似乎没有技术原因可以阻止这种情况,看起来只是进行实施工作的问题。