indexing - 如何避免使用负值?

标签 indexing rust

我正在将一大块(2000 行)专有 C 代码翻译成 Rust。在 C 语言中,将指针、数组索引等向下运行是很常见的,只要它是非负的。在 Rust 中,简化到骨子里,它看起来像这样:

while i >= 0 && more_conditions { 
    more_work;
    i -= 1;
}

当然,当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;
}

时不时地出现 panic ,如i_high跑过 0。

我一直在插入很多j_high >= 0 &&在代码中,它的可读性大大降低。

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

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

  2. 选角? i as usize , 检查 i < 0

  3. 将变量偏移 1,并使用 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);

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

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

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

最佳答案

如果你想按照惯用的方式去做:

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

注意在迭代器中使用 ..=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;
}

playground

关于indexing - 如何避免使用负值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52788350/

相关文章:

python - 弹出索引超出范围

php - 如何使用 MySQL 中保留的键和其他结构特征复制表?

rust - 为什么我可以为方法的 `&self` 参数强制引用移动语义,而不是函数参数?

rust - 尝试使用Rust tokio Framed LinesCodec写入服务器

mongodb - MongoDB 中数组的唯一索引

python - Numpy 高级索引 : same index used multiple times in +=

mysql - MYSQL表添加复合索引

rust - 从源构建奇偶校验后, cargo 构建挂起 "Blocking waiting for file lock on the registry index"

lifetime - 在 Rust 中生根管理值

docker - 在 google cloud 上用 docker 构建一个 rust 项目非常慢