我已经定义了一个宏来优雅地处理越界切片.以下是宏的定义:
macro_rules! slice_or_else {
($array: expr, $to:expr, $err: block) => ({
if $to <= $array.len() {
&$array[..$to]
}
else $err
})
}
Run Code Online (Sandbox Code Playgroud)
当我使用它编译一个函数时,编译器会抱怨
warning: comparison is useless due to type limits, #[warn(unused_comparisons)] on by default
Run Code Online (Sandbox Code Playgroud)
尽管使用比较确定请求的切片是否有效,以及宏是否通过测试.我错过了什么吗?可以为宏关闭这些警告吗?
更新:看来,通过0为$to引起该问题,如雷姆建议.一个例子(围栏示例):
fn main() {
let a: [u8; 4] = [0, 1, 2, 3];
assert!(slice_or_else!(a, 0, {return;}).len() == 0);
}
Run Code Online (Sandbox Code Playgroud)
我正在使用宏,因为我希望能够影响调用函数的流程.
由于警告是合理的,处理此用例的最佳策略是什么?绑定$to到临时变量?明确地投射它?
如果你使用这个$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(|| { &[] })
Run Code Online (Sandbox Code Playgroud)
除非必须使用宏,否则不应使用宏.
使用宏需要的东西:
你不需要使用宏的东西: