如何避免使用负面消极?

Pet*_*ter 1 indexing rust

我正在将一大块(2000行)的专有C代码翻译成Rust.在C中,通常将指针,数组索引等向下运行,只要它是非负的.在Rust中,简化为骨骼,它看起来像:

while i >= 0 && more_conditions { 
    more_work;
    i -= 1;
}
Run Code Online (Sandbox Code Playgroud)

当然,如果iusize,你得到的减法下溢出.我已经学会了通过使用for循环来解决这个问题,将.rev()索引偏移一个,或者使用不同的类型和使用as usize等等.

通常它可以工作,通常我可以使它清晰,但我正在修改的代码充满了彼此相互运行的索引,并最终进行了测试 i_low > i_high

像(在Rust)

loop {
    while condition1(i_low) { i_low += 1; }
    while condition2(i_high) { j_high -= 1; }
    if i_low > i_high { return something; }
    do_something_else;
}
Run Code Online (Sandbox Code Playgroud)

每隔一段时间就会出现这种恐慌,i_high从0开始.

j_high >= 0 &&在代码中插入了很多内容,但它的可读性却大打折扣.

经验丰富的Rust程序员如何避免usize变量变为-1?

  1. 换循环? for i in (0..size).rev()

  2. 铸件? i as usize,检查后i < 0

  3. 将变量偏移一个,并i-1在安全时使用?

  4. 额外的条件?

  5. 捕捉异常?

或者你最终是否学会围绕这些情况编写程序?


澄清:C代码没有被破坏 - 据说它已经生产了十年,在多个服务器上24/7构建视频片段.它只是不遵循Rust约定 - 它经常返回-1作为索引,它以-1为递归处理的数组的低索引递归,并且索引始终为负.所有这些都在问题发生之前得到处理 - 丑陋但功能齐全.就像是:

incident_segment = detect_incident(array, start, end);
attach(array, incident_segment);
store(array, start, incident_segment - 1);
process(array, incident_segment + 1, end);
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,三个结果调用中的每一个都可能获得一个段索引,即-1(附加,存储)或越界(进程)它已被处理,但是在调用之后.

我的Rust代码似乎也正常工作.事实上,为了处理负面的使用,我添加了额外的逻辑来修剪一些递归,因此它的运行速度与C代码一样快(显然更快,但这也是因为我将输出分配到多个驱动器)

问题是客户端不希望完全重写,并希望"本地"程序员能够相互检查两个程序.基于到目前为止的答案,我认为根据需要使用i64和cast/shadowing可能是生成易于为"本机"阅读的代码的最佳方式.我个人不必喜欢......

Opt*_*ach 5

如果你想用惯用语做:

for j in (0..=i).rev() {
    if conditions {
        break;
    }
    //use j as your new i here
}
Run Code Online (Sandbox Code Playgroud)

注意..=i在迭代器中使用这里,这意味着它实际上会迭代包括i:[0, 1, 2, ..., i-1, i]否则,你最终会得到[0, 1, 2, ..., i-2, i-1]

否则,这是代码:

while (i as isize - 1) != -2 && more_conditions { 
    more_work;
    i -= 1;
}
Run Code Online (Sandbox Code Playgroud)

操场