社区首页 >问答首页 >如何避免过大的负面影响?

如何避免过大的负面影响?
EN

Stack Overflow用户
提问于 2018-10-12 15:59:30
回答 2查看 1.8K关注 0票数 3

我正在将一大块(2000行)专有C代码转换为Rust。在C中,通常会向下运行指针、数组索引等,只要它是非负的。在“铁锈”中,简化为“骨头”,它看起来就像:

代码语言:javascript
代码运行次数:0
复制
while i >= 0 && more_conditions { 
    more_work;
    i -= 1;
}

当然,当iusize时,您会从减法中得到一个下溢出。我已经学会了如何使用for循环和.rev(),用一个抵消我的索引,或者使用不同的类型,使用as usize等等。

通常情况下,它可以工作,而且通常我可以让它清晰易懂,但是我正在修改的代码充满了相互间运行的索引,并最终用i_low > i_high进行了测试。

类似于(在锈病中)

代码语言:javascript
代码运行次数:0
复制
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;
}

随着i_high的运行超过0,这种恐慌时有发生。

我在代码中插入了大量的j_high >= 0 &&,而且它的可读性大大降低。

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

  1. 循环?for i in (0..size).rev()
  2. 铸造?i as usize,在检查i < 0之后
  3. 将变量偏移为一个,并在安全时使用i-1
  4. 额外的条件?
  5. 抓住例外?

还是你只是最终学会了围绕这些情况编写程序?

澄清:C代码并没有中断--据推测,它已经投入生产十年了,24/7在多台服务器上构建视频片段。它只是没有遵循锈蚀惯例--它通常会返回-1作为索引,然后再用-1来处理数组的低索引,索引一直为负值。所有这些都是在问题发生之前处理的--丑陋,但功能强大。类似于:

代码语言:javascript
代码运行次数:0
复制
incident_segment = detect_incident(array, start, end);
attach(array, incident_segment);
store(array, start, incident_segment - 1);
process(array, incident_segment + 1, end);

在上面的代码中,三个产生的调用中的每一个都可能得到一个段索引,即-1 (附加、存储)或超出边界(进程),但是在调用之后。

我的锈蚀代码似乎也有效。事实上,为了处理负的usize,我添加了额外的逻辑来修剪一些递归,所以它运行的速度和C代码一样快(显然更快,但这也是因为我将输出分配到多个驱动器上)。

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

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-12 18:01:51

如果你想成其为的话:

代码语言:javascript
代码运行次数:0
复制
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]

否则,下面是代码:

代码语言:javascript
代码运行次数:0
复制
while (i as isize - 1) != -2 && more_conditions { 
    more_work;
    i -= 1;
}

游乐场

票数 5
EN

Stack Overflow用户

发布于 2018-10-12 18:32:25

我可能首先使用saturating_sub (并行结构的_add ):

代码语言:javascript
代码运行次数:0
复制
while condition1(i_low) { i_low = i_low.saturating_add(1); }
while condition2(i_high) { j_high = j_high.saturating_sub(1); }

您需要小心,以确保您的逻辑处理的值饱和在零。您还可以在wrapping_sub中使用更多类似C的语义。

老实说,没有一刀切的解决办法。很多时候,如果你把复杂的逻辑抽象化一点,或者稍微把它侧转一下,它就会变得更简单。你没有提供任何具体的例子,所以我们不能给出任何有用的建议。我用迭代器解决了太多的问题,所以这通常是我的第一个解决方案。

捕获异常

绝对不是。这是非常低效和非惯用的。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52788350

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文