Structs - HimxhMC/HimDSL GitHub Wiki

struct 结构体 / Structs

为什么要结构体 / Why Structs

基本类型一次只能存一个值。当你想把"相关的几个值"放在一起时——例如一个玩家的名字、等级、血量、位置——就需要结构体。

Primitives hold one value at a time. When several related values belong together — a player's name, level, health, position — you need a struct.

结构体是"自己定义的类型"。定义一次,之后可以创建任意多个实例。

A struct is a "type you define yourself". Define it once, then create as many instances as you want.


定义一个结构体 / Defining a Struct

语法:

Syntax:

struct 名称 {
    类型 字段;
    类型 字段;
};

例子:

Example:

struct PlayerData {
    string name;
    int level;
    double health;
};

结尾的分号不能省。少了它会报语法错误。

The trailing semicolon is mandatory. Forget it and you get a syntax error.

字段名可以取任何合法标识符。字段名允许使用关键字(如 player、world、string),因为语法里字段名的规则比较宽松——不过为了避免混淆,还是建议取普通名字。

Field names may be any legal identifier. Keywords are allowed as field names (e.g. player, world, string) because the grammar is lenient there — but stick to ordinary names to avoid confusion.


创建实例 / Creating an Instance

声明一个结构体类型的变量,就创建了一个默认实例:

Declaring a variable of the struct type creates a default instance:

PlayerData data;        // 创建实例,字段都是默认值

字段的默认值:int 为 0,double 为 0,bool 为 false,string 为 null。

Default field values: int → 0, double → 0, bool → false, string → null.

也可以直接声明并赋值:

You may also declare and assign at once:

PlayerData data = PlayerData();

PlayerData() 与不写初始值效果相同。注意不要写成 new PlayerData()——new 关键字是留给 Java 类的,对它用在结构体上会失败。

PlayerData() is equivalent to leaving it out. Do not write new PlayerData() — new is reserved for Java classes and fails on structs.


访问字段 / Accessing Fields

用点号访问字段:

Access fields with a dot:

PlayerData data;

data.name = "Steve";
data.level = 30;
data.health = 20.0;

读取同样:

Read the same way:

string name = data.name;
int level = data.level;

不要写 getter 或 setter。字段是公开的,直接用点号读写。

Do not write getters or setters. Fields are public; use the dot directly.


一个完整的例子 / A Complete Example

struct PlayerData {
    string name;
    int level;
    double health;
};

int main() {
    // 创建两个实例
    PlayerData a;
    a.name = "Steve";
    a.level = 30;
    a.health = 20.0;

    PlayerData b;
    b.name = "Alex";
    b.level = 25;
    b.health = 18.0;

    // 使用
    runcmd("CONSOLE", "say " + a.name + " 等级 " + a.level);
    runcmd("CONSOLE", "say " + b.name + " 等级 " + b.level);
}

每个 PlayerData 变量是独立的。修改 a 不影响 b。

Each PlayerData variable is independent. Changing a does not affect b.


结构体作为函数参数 / Structs as Function Parameters

结构体可以作为函数的参数或返回值:

Structs work as function parameters and return values:

PlayerData makePlayer(string name, int level) {
    PlayerData d;
    d.name = name;
    d.level = level;
    d.health = 20.0;
    return d;
}

void printInfo(PlayerData d) {
    runcmd("CONSOLE", "say " + d.name + " / " + d.level);
}

int main() {
    PlayerData p = makePlayer("Steve", 30);
    printInfo(p);
}

结构体是引用传递。函数里修改参数的字段,会影响调用方的实例:

Structs pass by reference. Modifying a parameter's field affects the caller's instance:

void levelUp(PlayerData d) {
    d.level += 1;           // 会影响调用方的 d
}

int main() {
    PlayerData p;
    p.level = 10;
    levelUp(p);
    runcmd("CONSOLE", "say " + p.level);    // 11
}

这与基本类型的"值传递"不同。基本类型是副本,结构体是引用。

This differs from primitives, which pass by value. Primitives are copies; structs are references.


结构体作为数组元素 / Structs in Arrays and Lists

结构体可以装进数组或列表,用来管理一批同类数据:

Structs fit in arrays and lists to manage a batch:

var players = vector();

PlayerData a;
a.name = "Steve";
a.level = 30;
players.add(a);

PlayerData b;
b.name = "Alex";
b.level = 25;
players.add(b);

for (int i = 0; i < players.size(); i = i + 1) {
    var p = players.get(i);
    runcmd("CONSOLE", "say " + p.name);
}

注意遍历时用 var p = players.get(i),因为 players 是列表,元素的静态类型未知。

Note var p = players.get(i) when iterating, since the list has no declared element type.


常见错误 / Common Mistakes

错误一:忘了分号

struct Point {
    int x;
    int y;
}       // ✗ 缺少分号

结构体定义的结尾必须有分号。

错误二:用 new 创建

Point p = new Point();      // ✗ new 只用于 Java 类

结构体用 Point p; 或 Point p = Point();。

错误三:字段名拼错

访问不存在的字段会报"字段不存在":

struct Point { int x; int y; };

Point p;
p.z = 5;                    // ✗ Point 没有字段 z

Mistake 1: Missing semicolon

Struct definitions end with a semicolon.

Mistake 2: Using new

new is for Java classes only. Use Point p;.

Mistake 3: Misspelled field name

Accessing a non-existent field errors.


小结 / Summary

  • 定义:struct 名称 { 类型 字段; ... };,结尾分号。

  • 创建:名称 变量; 或 名称 变量 = 名称();。

  • 字段访问:变量.字段,读写都用点号。

  • 不要写 getter/setter。

  • 结构体引用传递,函数内修改字段影响调用方。

  • 字段名可用关键字,但建议用普通名字。

  • Define: struct Name { type field; ... }; — semicolon at the end.

  • Create: Name var; or Name var = Name();.

  • Access: var.field; read and write with a dot.

  • No getters/setters.

  • Structs pass by reference; changes affect the caller.

  • Keywords allowed as field names but avoid them.


下一步 / Next Steps

下一章 [结构体方法绑定 / Struct-Method-Binding] 介绍如何在结构体里定义方法,以及方法如何读写字段。

Next, [结构体方法绑定 / Struct-Method-Binding] shows defining methods on structs and how methods read/write fields.