假设我有这样的伪代码:

bool conditionA = executeStepA();
if (conditionA){
    bool conditionB = executeStepB();
    if (conditionB){
        bool conditionC = executeStepC();
        if (conditionC){
            ...
        }
    }
}

executeThisFunctionInAnyCase();

函数executeStepX当且仅当前一个成功时执行。 在任何情况下,executeThisFunctionInAnyCase函数都应该在最后被调用。 我在编程方面是一个新手,所以很抱歉提出一个非常基本的问题:有没有一种方法(例如在C/ c++中)以代码易读性为代价,避免长if链产生那种“金字塔式代码”?

我知道如果我们可以跳过executeThisFunctionInAnyCase函数调用,代码可以简化为:

bool conditionA = executeStepA();
if (!conditionA) return;
bool conditionB = executeStepB();
if (!conditionB) return;
bool conditionC = executeStepC();
if (!conditionC) return;

但是约束是executeThisFunctionInAnyCase函数调用。 break语句可以以某种方式使用吗?


当前回答

只是一个边注;如果if作用域总是导致返回(或循环中断),则不要使用else语句。这可以节省大量的缩进。

其他回答

为什么使用OOP?在伪代码:

abstract class Abstraction():
   function executeStepA(){...};
   function executeStepB(){...};   
   function executeStepC(){...};
   function executeThisFunctionInAnyCase(){....}
   abstract function execute():

class A(Abstraction){
   function execute(){
      executeStepA();
      executeStepB();
      executeStepC();
   }
}
 class B(Abstraction){
   function execute(){
      executeStepA();
      executeStepB();
   }
}
class C(Abstraction){
     function execute(){
       executeStepA();
     }
}

这样你的如果就消失了

item.execute();
item.executeThisFunctionInAnyCase();

通常,使用OOP可以避免if。

似乎你想在一个block中完成所有的调用。 正如其他人所建议的那样,你应该使用while循环并使用break离开,或者使用一个可以使用return离开的新函数(可能更干净)。

我个人排斥goto,即使是函数退出。在调试时很难发现它们。

一个适合您的工作流的优雅替代方法是构建一个函数数组并在此基础上迭代。

const int STEP_ARRAY_COUNT = 3;
bool (*stepsArray[])() = {
   executeStepA, executeStepB, executeStepC
};

for (int i=0; i<STEP_ARRAY_COUNT; ++i) {
    if (!stepsArray[i]()) {
        break;
    }
}

executeThisFunctionInAnyCase();

我认为c++ 23的可选的一元操作会做得很好,尽管函数需要做一些改变。

and_then()方法执行break或调用下一个函数操作,链接该方法允许逐个调用函数,直到其中一个返回false。

举个简单粗暴的例子:

#include <iostream>
#include <optional>
#include <cstdlib>

using namespace std;

optional<bool> func1() {
    cout << "func1\n";

    if (rand() % 2)
        return true;
    else
        return nullopt;
}

optional<bool> func2(optional<bool> v) {
    cout << "func2\n";

    if (rand() % 2)
        return true;
    else
        return nullopt;
}

optional<bool> func3(optional<bool> v) {
    cout << "func3\n";

    if (rand() % 2)
        return true;
    else
        return nullopt;
}

void func4() {
    cout << "func4\n";
}

int main() {
    srand(time(NULL));

    func1()
      .and_then(func2)
      .and_then(func3);

    func4();

    return 0;
}

只需使用一个额外的函数来让你的第二个版本工作:

void foo()
{
  bool conditionA = executeStepA();
  if (!conditionA) return;

  bool conditionB = executeStepB();
  if (!conditionB) return;

  bool conditionC = executeStepC();
  if (!conditionC) return;
}

void bar()
{
  foo();
  executeThisFunctionInAnyCase();
}

使用深度嵌套的if(你的第一个变体)或者想要跳出“函数的一部分”通常意味着你确实需要一个额外的函数。

你可以使用&&(逻辑与):

if (executeStepA() && executeStepB() && executeStepC()){
    ...
}
executeThisFunctionInAnyCase();

这将满足你的两个要求:

executeStep<X>()应该只在前一个成功时才计算(这称为短路计算) executeThisFunctionInAnyCase()将在任何情况下执行