Break Continue Return - HimxhMC/HimDSL GitHub Wiki

break / continue / return

三个关键字 / Three Keywords

  • break —— 跳出当前循环。

  • continue —— 跳过本次迭代,直接进入下一次。

  • return —— 结束当前函数,可以带一个返回值。

  • break — exit the loop.

  • continue — skip the rest of this iteration, jump to the next.

  • return — exit the current function, optionally returning a value.

三者在循环和函数里各有用处,本章逐个讲解。

Each has its place in loops and functions; this chapter covers them in order.


break:提前跳出 / break: Exit Early

break 立即终止当前所在的循环,跳到循环后面的语句。

break immediately terminates the innermost enclosing loop.

var players = @a;
for (int i = 0; i < players.size(); i = i + 1) {
    var p = players.get(i);
    if (p.name == "Steve") {
        runcmd("CONSOLE", "say 找到 Steve");
        break;              // 找到就停,不再继续遍历
    }
}

用途:一旦找到想要的结果就停,避免无谓的遍历。

Use case: stop once you find what you want, avoiding unnecessary iterations.

只跳出最内层 / Exits Only the Innermost Loop

嵌套循环中,break 只跳出它所在的那一层:

In nested loops, break exits only its own level:

for (int i = 0; i < 3; i++) {
    for (int j = 0; j < 3; j++) {
        if (j == 1) {
            break;          // 只跳出内层循环
        }
    }
    // 外层继续执行
}

要跳出多层循环,可以用一个标志变量,或者把循环拆成一个函数然后 return(下面会讲)。

To exit multiple levels, use a flag variable, or wrap the loop in a function and return (see below).


continue:跳过本次 / continue: Skip This Iteration

continue 跳过循环体剩余部分,直接进入下一次迭代。

continue skips the rest of the body and jumps to the next iteration.

var players = @a;
for (int i = 0; i < players.size(); i = i + 1) {
    var p = players.get(i);
    if (p.health <= 0) {
        continue;           // 血量 <= 0 的跳过
    }
    runcmd("CONSOLE", "say " + p.name + " 存活");
}

对于 for 循环,continue 之后会执行更新部分,再检查条件。这一点与 while 稍有不同:while 里 continue 之后直接检查条件,如果更新语句在循环体末尾,就会被跳过(见后文"陷阱")。

For for, continue runs the update next, then checks the condition. In while, continue re-checks the condition directly; if the update is at the body's end, it gets skipped (see "Pitfalls").


return:结束函数 / return: Exit the Function

return 结束当前函数。可以带一个值作为返回值,也可以不带。

return exits the current function, optionally with a value.

无返回值的 return

用于 void 函数,或者从函数中途退出:

For void functions, or to exit early:

void checkPlayer(player p) {
    if (p == null) {
        runcmd("CONSOLE", "say 玩家为空");
        return;                 // 提前退出
    }
    runcmd("CONSOLE", "say " + p.name);
}

带返回值的 return

int max(int a, int b) {
    if (a > b) {
        return a;
    }
    return b;
}

调用者接收返回值:

Caller receives it:

int m = max(3, 7);       // m = 7

在循环里 return

return 会直接结束整个函数,包括它所在的循环:

return ends the entire function, loop included:

bool contains(string[] names, string target) {
    for (int i = 0; i < names.size(); i = i + 1) {
        if (names.get(i) == target) {
            return true;        // 直接返回,循环和函数一起结束
        }
    }
    return false;               // 全部遍历完,没找到
}

这是 return 和 break 的关键区别:break 只跳出循环,函数继续;return 结束函数。

This is the key difference: break exits the loop and the function continues; return ends the function.


用 return 替代嵌套 / Replacing Nesting with return

上上一章提到过"嵌套不要超过三层",return 正是解决办法。用提前 return 把深层嵌套"压平":

The earlier chapter advised "no more than three levels". return is the fix — flatten deep nesting with early returns:

// 嵌套写法
void process(player p) {
    if (p != null) {
        if (p.health > 0) {
            if (p.world == "world") {
                runcmd("CONSOLE", "say 处理 " + p.name);
            }
        }
    }
}

// 提前 return 写法
void process(player p) {
    if (p == null) return;
    if (p.health <= 0) return;
    if (p.world != "world") return;

    runcmd("CONSOLE", "say 处理 " + p.name);
}

后者读起来从上到下一路走到底,不用在心里记住"现在在第几层"。推荐后者。

The latter reads top-down without tracking "how deep am I". Prefer it.


陷阱一:while 里的 continue / Pitfall 1: continue in while

continue 在 while 里会直接跳到条件检查。如果循环的更新语句在 continue 之后,它就被跳过了:

continue in while jumps straight to the condition. If the update sits after continue, it is skipped:

int i = 0;
while (i < 10) {
    if (i == 5) {
        continue;       // ✗ 死循环:i 永远停在 5
    }
    i++;                // 永远执行不到
}

修复方式:把更新移到 continue 之前。

Fix: move the update before continue:

while (i < 10) {
    i++;
    if (i == 5) {
        continue;
    }
    // ...
}

这是用 while 的经典陷阱。遍历列表时优先用 for 就能避开它,因为 for 的更新部分在 continue 后一定会执行。

This is the classic while pitfall. Prefer for when iterating — its update always runs after continue.


陷阱二:break 在 switch 里 / Pitfall 2: break in switch

HimDSL 没有 switch 语句。想根据多个值分支,用 if / else if 链:

HimDSL has no switch statement. Use if / else if chains:

if (rank == "admin") {
    runcmd("CONSOLE", "say 管理员");
} else if (rank == "mod") {
    runcmd("CONSOLE", "say 管理员助理");
} else {
    runcmd("CONSOLE", "say 普通玩家");
}

陷阱三:在 lambda 里 return / Pitfall 3: return in a lambda

lambda 里的 return 只退出 lambda 本身,不会穿透到外层函数。

return inside a lambda exits the lambda only, not the outer function.

void process() {
    for (int i = 0; i < 10; i = i + 1) {
        var cb = (int x) -> {
            if (x > 5) {
                return;             // 只退出 lambda
            }
            runcmd("CONSOLE", "say " + x);
        };
        cb.apply(i);
    }
    runcmd("CONSOLE", "say 循环结束");
}

即使 lambda 里 return 了,外层的 for 依然会继续。想要穿透,可以用标志变量或者把逻辑直接写在循环体内。

Even if the lambda returns, the outer for continues. To break through, use a flag variable or inline the logic.


小结 / Summary

  • break 跳出当前循环。

  • continue 跳过本次迭代,进入下一次。

  • return 结束整个函数,可以带值。

  • while 里的 continue 要小心更新语句的位置。

  • 用提前 return 压平嵌套。

  • lambda 里的 return 只退出 lambda。

  • break exits the current loop.

  • continue skips to the next iteration.

  • return exits the whole function, optionally with a value.

  • continue in while needs care about update placement.

  • Flatten nesting with early return.

  • return inside a lambda exits the lambda only.


控制流部分回顾 / Control Flow Review

到此,控制流部分讲完了四章:条件分支、for 循环、while 与 do-while、break / continue / return。这四章覆盖了脚本中所有"根据条件做不同的事"和"重复做某件事"的语法。后面的章节会大量使用这些结构,但不会再引入新的控制流语法。

The Control Flow section ends here: conditionals, for, while / do-while, break / continue / return. These four chapters cover every way to branch and repeat. Later chapters rely on these constructs but will not introduce new control-flow syntax.


下一步 / Next Steps

下一部分进入函数。第十章 [定义函数 / Defining-Functions] 从最简单的函数写起,逐步引入参数、返回值、重载。之前脚本里写过的 main 就是一个函数。

The next part covers functions. Chapter [定义函数 / Defining-Functions] starts from the simplest function and builds up to parameters, return values, and overloading. The main you have been writing is already a function.