如何重构这个GOTO(不涉及资源释放)



这是一个简单的控制流GOTO问题,与资源分配无关。

检查一段数据是否"好"有两个层次。当且仅当通过第一次检查时,执行第二次检查。如果数据没有通过任何一个测试,则使用默认值。

第二次检查涉及到中间数据的几个步骤,所以我们不能只把它放在短路的||条件下。此外,如果第二个测试通过,我们使用第二个测试的输出而不是原始数据。

这是实时处理情况下的内循环,因此效率非常重要。我们不希望做任何计算超过一次。

if (firstCheck(data)) {
    result = analyze(data);
    if (secondCheck(result)) {
        use_result(result);
    }
    else {
        goto FAIL;
    }
}
else {
FAIL:
    use_result(DEFAULT_VALUE);
}

这个GOTO似乎以最大的效率满足了我的所有要求。我可以想到其他一些方法,但都需要额外的存储空间或条件。不过我对goto很警惕。事实上,如果我使用这个,这将是我第一次使用GOTO。所以求你了,帮我找到出去的路!

使用continue进入下一个循环迭代

if (firstCheck(data)) {
    result = analyze(data);
    if (secondCheck(result)) {
        use_result(result);
        continue;
    }
}
use_result(DEFAULT_VALUE);

我们可以不做太多的工作来修复这个问题,但是以这种方式使用goto并不一定是不好的行为-例如linux内核使用这种约定来做错误处理只有一个点,我认为代码是相当清晰的。

使用异常来解决这个问题显然是一个解决方案,但是在错误的情况下,这会降低性能,所以我认为这是不可能的。

所以如果你想,这应该是好的:

if (firstCheck(data) && secondCheck(result = analyze(data)) {
    use_result(result);
}
else {
    // fail
}

你不只是在使用goto。您正在使用进入另一个作用域的goto。更简单:

if (firstCheck(data)) {
    result = analyze(data);
    use_result (secondCheck (result) ? result : DEFAULT_VALUE);
}
else {
    use_result(DEFAULT_VALUE);
}

更简洁,无代码重复,可伸缩:

int result = DEFAULT_VALUE;
if (firstCheck(data)) {
    int tmpResult = analyze(data);
    if (secondCheck (tmpResult))
        result = tmpResult;
}
use_result (result);

相关内容

  • 没有找到相关文章

最新更新