Skip to content

Defining Functions

Himxh edited this page Oct 4, 2026 · 1 revision

定义函数 / Defining Functions

从 main 说起 / Starting from main

从第一章起,你写的每个脚本都有一个 main 函数:

Since chapter one, every script has had a main function:

int main() {
    runcmd("CONSOLE", "say 你好");
}

main 是脚本的入口,服务器加载脚本时会找到它并执行。但脚本里可以不止 main 一个函数。你可以定义任意多个函数,main 里调用它们,把逻辑拆成小块。

main is the entry point. But a script may hold more than one function. You can define as many as you like, and main can call them, splitting logic into small pieces.


定义一个函数 / Defining a Function

函数的语法:

The function syntax:

返回类型 函数名(参数列表) {
    函数体
}

例子:

Example:

int doubleIt(int x) {
    return x * 2;
}
  • int 是返回类型,函数结束时必须返回一个整数。

  • doubleIt 是函数名,用驼峰命名法。

  • (int x) 是参数列表,一个名为 x 的整数参数。

  • return x * 2; 返回计算结果。

  • int is the return type; the function must return an integer.

  • doubleIt is the name, camelCase by convention.

  • (int x) is the parameter list, one integer parameter named x.

  • return x * 2; produces the result.

调用它:

Call it:

int main() {
    int n = doubleIt(5);
    runcmd("CONSOLE", "say " + n);      // 10
}

返回类型 / Return Types

四种基本类型都可以作为返回类型,加上 void 表示"不返回值":

Any of the four basic types may be a return type, plus void for "no value":

int    add(int a, int b)    { return a + b; }
double half(double x)       { return x / 2.0; }
bool   isAdult(int age)     { return age >= 18; }
string greet(string name)   { return "你好," + name; }
void   log(string msg)      { runcmd("CONSOLE", "say " + msg); }

void 函数里可以写 return;(没有值),用来提前退出:

In a void function you may write return; (no value) for early exit:

void check(int hp) {
    if (hp <= 0) {
        runcmd("CONSOLE", "say 已死亡");
        return;
    }
    runcmd("CONSOLE", "say 存活");
}

void 函数不能出现在表达式中。写 int x = log("hi"); 会报错,因为 log 没有返回值。

A void function cannot appear inside an expression. int x = log("hi"); errors because log returns nothing.


参数 / Parameters

参数列在括号内,用逗号分隔。每个参数都要写类型:

Parameters go inside the parentheses, separated by commas. Each parameter has a type:

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

没有参数时括号留空(不能省):

With no parameters, keep the parentheses (they cannot be omitted):

int answer() {
    return 42;
}

参数是局部变量 / Parameters Are Local

参数在函数内部就像普通变量一样使用,函数结束时消失。函数外看不见它们,函数之间也互不影响:

Parameters behave like ordinary variables inside the function and vanish when it returns. They are invisible outside, and functions do not interfere with each other's parameters:

int f(int x) {
    x = x + 1;          // 只修改 f 内部的 x
    return x;
}

int main() {
    int a = 5;
    int b = f(a);        // b = 6, a 仍是 5
}

这种"传入的是副本"的行为称为值传递。基本类型(int、double、bool、string)都是值传递。

This "copy on call" behavior is called pass by value. Primitives (int, double, bool, string) all pass by value.


返回值与 return / Return and Its Value

return 语句结束函数并返回一个值:

return ends the function and produces a value:

int square(int x) {
    return x * x;
}

一个函数里可以有多条 return,第一条执行到的 return 就结束函数:

A function may contain several returns; the first one reached ends the function:

string describe(int hp) {
    if (hp <= 0) return "死亡";
    if (hp < 10) return "危险";
    if (hp < 20) return "一般";
    return "健康";
}

这种写法很常见:先处理特殊情况,最后留一个兜底 return。

This pattern is common: handle special cases first, leave a fallback return at the end.

如果函数声明了非 void 的返回类型,但某条执行路径没有 return,脚本运行时不会报错,而是返回 null。这可能导致后续逻辑莫名其妙地失败。写有返回值的函数时,确保每条路径都有 return。

If a non-void function has a path that never hits return, the runtime does not error — it returns null. This can cause confusing downstream failures. When writing a value-returning function, make sure every path returns.


函数之间的调用 / Calling Other Functions

函数可以互相调用,顺序不影响——定义可以在调用之前或之后:

Functions may call one another; order does not matter — a definition may come before or after the call:

int main() {
    int r = doubleIt(5);
    runcmd("CONSOLE", "say " + r);
}

int doubleIt(int x) {
    return x * 2;
}

main 引用了后面才定义的 doubleIt,没有问题。脚本加载时会先收集所有函数,再执行 main。

main refers to doubleIt defined later, and it works. The script collects every function first, then runs main.

函数可以调用自己,这叫递归。递归的写法与普通调用一样,我们会在示例章节里专门讲。

A function may call itself; this is recursion. The syntax is identical to an ordinary call; example scripts will cover it later.


一个完整的例子 / A Complete Example

把常用的小工具写成函数,脚本会变得更好读:

Pulling small utilities into functions makes scripts more readable:

int clamp(int value, int lo, int hi) {
    if (value < lo) return lo;
    if (value > hi) return hi;
    return value;
}

string repeat(string s, int n) {
    string out = "";
    for (int i = 0; i < n; i = i + 1) {
        out += s;
    }
    return out;
}

int main() {
    int hp = clamp(150, 0, 100);
    runcmd("CONSOLE", "say 血量 " + hp);

    string bar = repeat("=", 20);
    runcmd("CONSOLE", "say " + bar);
}

clamp 把数字限制在指定区间内,repeat 重复字符串。这两个函数在后面的示例里还会出现。

clamp restricts a number to a range, and repeat repeats a string. Both reappear in later examples.


小结 / Summary

  • 函数语法:返回类型 名称(参数) { 函数体 }。

  • 返回类型可以是 int / double / bool / string / void。

  • 参数是局部变量,值传递。

  • 多条 return 时,第一条执行到的结束函数。

  • 非 void 函数要保证每条路径都有 return。

  • 定义顺序不影响调用。

  • Syntax: returnType name(params) { body }.

  • Return types: int / double / bool / string / void.

  • Parameters are local, passed by value.

  • With multiple returns, the first reached wins.

  • Non-void functions must return on every path.

  • Definition order does not matter.


下一步 / Next Steps

下一章 [函数重载 / Function-Overloading] 介绍同名函数的多种版本。

Next, [函数重载 / Function-Overloading] introduces multiple versions of the same function name.


HimDSL 文档 / Documentation

入门 / Getting Started

语言基础 / Language Basics

控制流 / Control Flow

函数 / Functions

数据结构 / Data Structures

自定义类型 / Custom Types

Minecraft 集成 / Minecraft Integration

事件与调度 / Events & Scheduling

GUI 系统 / GUI System

内置函数参考 / Built-ins Reference

进阶 / Advanced

扩展 API / Extension API

你真的需要 API 吗?/ Do you really need the API?

Clone this wiki locally