Zigの構造体と列挙型

Zigプログラミング言語において、構造体(struct)と列挙型(enum)は2つの基本的なデータ型です。

構造体と列挙型は、カスタムデータ型を定義して使用するための2つの主要な方法です。

構造体と列挙型は、より高レベルのデータ整理と型安全性を提供し、さまざまなプログラミングシーンに適しています。

  • 構造体(Struct):関連する変数を1つの複合データ型にまとめるために使用します。構造体はフィールドとメソッドを含むことができ、複雑なデータを整理するのに適しています。
  • 枚举(Enum):名前付きの定数のセットを定義するために使用され、値を持たない場合と値を持つ場合があります。列挙型は有限の離散値を表現するのに適しています。

構造体(Struct)

構造体は複合データ型であり、複数の異なる型のデータ項目を1つの型にまとめることができます。

Zigにおける構造体の構文は以下の通りです:

const structName = struct {
    field1: FieldType1,
    field2: FieldType2,
    // 其他字段
};

以下のコードでは、MyStruct は構造体型であり、3つのフィールドを持ちます。field1 は32ビット整数、field2 は倍精度浮動小数点数、field3 はバイト配列へのポインタです。

struct MyStruct {
    field1: i32,
    field2: f64,
    field3: []const u8,
}

实例

const std = @import("std");

// 定义一个结构体
const Person = struct {
    name: []const u8,
    age: u32,
};

pub fn main() void {
    // 创建结构体实例
    const person = Person{
        .name = "Alice",
        .age = 30,
    };

    // 访问结构体字段并正确格式化
    std.debug.print("Name: {s}\n", .{person.name}); // 使用 {s} 格式化切片
    std.debug.print("Age: {}\n", .{person.age});
}

上記のコードをコンパイルして実行すると、出力結果は次のようになります:

Name: Alice
Age: 30

構造体のフィールドを変更するには、varを使用して構造体インスタンスを定義してください。そうすることでフィールド値を変更できます。constを使用して構造体インスタンスを定義した場合、そのフィールド値を変更することはできません。

实例

const std = @import("std");

// 定义一个结构体
const Person = struct {
    name: []const u8,
    age: u32,
};

pub fn main() void {
    // 创建结构体实例
    var person = Person{
        .name = "Alice",
        .age = 30,
    };

    // 输出初始值
    std.debug.print("Initial Name: {s}\n", .{person.name});
    std.debug.print("Initial Age: {}\n", .{person.age});

    // 構造体のフィールドの値を変更する
    person.name = "Bob";
    person.age = 35;

    // 変更後の値を出力
    std.debug.print("Modified Name: {s}\n", .{person.name});
    std.debug.print("Modified Age: {}\n", .{person.age});
}

上記のコードをコンパイルして実行すると、出力結果は次のようになります:

Initial Name: Alice
Initial Age: 30
Modified Name: Bob
Modified Age: 35

方法

Zigでは、構造体メソッドは fn キーワードで定義され、他のプログラミング言語のクラスメソッドに似ています。

实例

const std = @import("std");

const Rectangle = struct {
    width: u32,
    height: u32,

    // 面積を計算するメソッド
    fn area(self: Rectangle) u32 {
        return self.width * self.height;
    }
};

pub fn main() void {
    var rect = Rectangle{
        .width = 10,
        .height = 5,
    };

    // 调用结构体方法
    std.debug.print("Area: {}\n", .{rect.area()});
}

上記のコードをコンパイルして実行すると、出力結果は次のようになります:

Area: 50

枚举(Enum)

列挙型はデータ型の一種であり、固定された一連の定数値で構成されます。

Zigにおける列挙型の構文は以下の通りです:

const enumName = enum {
    Variant1,
    Variant2,
    // 其他变体
};

以下のコードでは、MyEnum は列挙型であり、Option1、Option2、Option3 の3つの可能な値を持ちます。

enum MyEnum {
    Option1,
    Option2,
    Option3,
}

实例

const std = @import("std");

// 定义一个枚举
const Color = enum {
    Red,
    Green,
    Blue,
};

pub fn main() void {
    // 使用枚举
    const favoriteColor = Color.Green;

    switch (favoriteColor) {
        Color.Red => std.debug.print("Red\n", .{}),
        Color.Green => std.debug.print("Green\n", .{}),
        Color.Blue => std.debug.print("Blue\n", .{}),
    }
}

上記のコードをコンパイルして実行すると、出力結果は次のようになります:

Green

値を持つ列挙型

Zigでは、列挙型の各バリアントに具体的な値を指定できます。これにより、より多くの情報を表現したり、比較を行ったりできます。

实例

const std = @import("std");

// 値を持つ列挙型を定義する
const Status = enum(u32) {
    Pending = 1,
    InProgress = 2,
    Completed = 3,
};

pub fn main() void {
    const taskStatus = Status.InProgress;

    switch (taskStatus) {
        Status.Pending => std.debug.print("Pending\n", .{}),
        Status.InProgress => std.debug.print("InProgress\n", .{}),
        Status.Completed => std.debug.print("Completed\n", .{}),
    }
}

上記のコードをコンパイルして実行すると、出力結果は次のようになります:

InProgress

列挙型をフィールドとして使用する

列挙型は構造体のフィールドとして使用でき、構造体をより柔軟で強力にします。

实例

const std = @import("std");

const Status = enum {
    Active,
    Inactive,
    Suspended,
};

const User = struct {
    name: []const u8,
    status: Status,
};

pub fn main() void {
    // 创建 User 实例
    const user = User{
        .name = "Alice",
        .status = Status.Active,
    };

    // User の name フィールドを出力します。
    std.debug.print("User: {s}\n", .{user.name}); // 使用 {s} 格式化切片

    // switch 文を使用して、status に応じて異なる状態を出力する
    switch (user.status) {
        Status.Active => std.debug.print("Status: Active\n", .{}),
        Status.Inactive => std.debug.print("Status: Inactive\n", .{}),
        Status.Suspended => std.debug.print("Status: Suspended\n", .{}),
    }
}

上記のコードをコンパイルして実行すると、出力結果は次のようになります:

User: Alice
Status: Active
其他扩展