我已经定义了一个宏来优雅地处理越界切片。以下是宏的定义:
macro_rules! slice_or_else {
($array: expr, $to:expr, $err: block) => ({
if $to <= $array.len() {
&$array[..$to]
}
else $err
})
}
当我使用它编译一个函数时,编译器会抱怨
warning: comparison is useless due to type limits, #[warn(unused_comparisons)] on by default
尽管使用比较确定请求的切片是否有效,以及宏是否通过测试。我错过了什么吗?是否可以为宏关闭这些警告?
更新:正如Reem建议的那样,将0
作为$to
传递会导致问题。一个例子(Playpen Example):
fn main() {
let a: [u8; 4] = [0, 1, 2, 3];
assert!(slice_or_else!(a, 0, {return;}).len() == 0);
}
我正在使用宏,因为我希望能够影响调用函数的流程。
由于警告是合理的,处理此用例的最佳策略是什么?将$to
绑定到临时变量?明确地投射它?
答案 0 :(得分:5)
如果您使用此$to
设置为0
的宏,那么rustc会抱怨,因为0 <= X
始终为真,因为我们正在处理usize
,这是无符号的。请注意,&x[..0]
永远不会触发越界错误。
在相关的说明中,这是编写此代码的更惯用的方法:
fn slice_opt<T>(buf: &[T], ind: usize) -> Option<&[T]> {
if ind <= buf.len() {
Some(&buf[..ind])
} else {
None
}
}
// Usage site // $err
slice_opt(x).unwrap_or_else(|| { &[] })
除非必须使用宏,否则不应使用宏。
使用宏需要的东西:
您不需要使用宏的东西: