Zig 配列とスライス

Zigプログラミング言語において、配列とスライスは、同じ型のデータの集合を格納・操作するための基本的な構造です。

  • 数组:同じ型のデータを固定サイズで格納するために使用され、定義時にサイズを指定し、スタック上に格納されます。
  • 切片:配列や他の連続したメモリ領域の一部を参照するために使用され、サイズを動的に調整でき、より柔軟で、通常はヒープメモリを参照します。

数组(Array):

  • 配列は固定長のシーケンスであり、そのサイズはコンパイル時に決定されます。
  • 配列の型は[T],其中T配列内の要素の型です。
  • 配列のメモリは連続しているため、特に大量のデータを扱う場合にパフォーマンス面で優れています。

切片(Slice):

  • スライスは動的な長さを持つシーケンスで、実行時にサイズを変更できます。
  • スライスの型は[]T,其中Tスライス内の要素の型です。
  • スライスは実際には配列への参照であり、配列を指すポインタとスライスの長さを含みます。
  • スライスは、異なる配列間で簡単に共有・受け渡しができるため、データをより柔軟に扱うことができます。

数组

配列は固定サイズでスタック上に格納され、要素の型はすべて同じである必要があります。

可以使用[]配列を定義し、配列のサイズを指定するための構文。

配列の型は次のように定義される[T; N]、ここでTは配列の要素の型、Nは配列の長さです。

配列の要素にはインデックスでアクセスでき、インデックスは0开始。

语法格式

const arrayName: [size]ElementType = [size]ElementType{element1, element2, ...};

参数说明:

  • arrayName:配列の名前。
  • size:配列のサイズ(要素数)であり、コンパイル時の定数です。
  • ElementType:配列内の要素の型です。
  • element1, element2, ...:配列内の要素。

配列は固定サイズの連続したメモリブロックであり、そのサイズはコンパイル時に決定されます:

var myArray: [10]u8 = [10]u8{0} ** 10; // 定义并初始化一个大小为 10 的 u8 类型数组

实例

const std = @import("std");

pub fn main() void {
    // 5つのi32型要素を含む配列を定義する
    const arr: [5]i32 = [5]i32{1, 2, 3, 4, 5};

    // 通过索引访问数组元素
    std.debug.print("First element: {}\n", .{arr[0]});
    std.debug.print("Third element: {}\n", .{arr[2]});

    // 配列のサイズは固定されている
    const size: usize = arr.len;
    std.debug.print("Array size: {}\n", .{size});
}

コンパイル出力結果は:

First element: 1
Third element: 3
Array size: 5

遍历数组

可以使用forループを使用して配列の要素を走査します。

实例

const std = @import("std");

pub fn main() void {
    const arr: [5]i32 = [5]i32{ 1, 2, 3, 4, 5 };

    var index: usize = 0;

    // 遍历数组
    for (arr) |item| {
        std.debug.print("Index: {}, Item: {}\n", .{ index, item });
        index += 1;
    }
}

コンパイル出力結果は:

Index: 0, Item: 1
Index: 1, Item: 2
Index: 2, Item: 3
Index: 3, Item: 4
Index: 4, Item: 5

切片(Slice)

スライスは、配列や他の連続したメモリ領域の一部への参照です。

スライスは動的にサイズを変更でき、配列よりも柔軟ですが、その要素はヒープ上に格納されます。

定義と初期化

スライスは、配列や他の連続したメモリ領域の一部への参照です。

スライスは動的であり、そのサイズを変更でき、通常は配列の一部や動的に割り当てられたメモリブロックを表すために使用されます。

语法格式

const sliceName: []ElementType = array[start..end];

参数说明:

  • sliceName:スライスの名前。
  • ElementType:スライス内の要素の型です。
  • array[start..end]:からarrayから部分スライスを抽出し、startとendインデックスです。

スライスは、配列の部分集合から作成することも、ポインタと長さから作成することもできます:

var myArray: [10]u8 = ...; // 假设已经初始化
var mySlice = myArray[2..7]; // 创建一个切片,包含索引2到6的元素

// 或者使用指针和长度
var mySlicePtr = myArray[2..]; // 创建一个切片,从索引2开始到数组末尾

スライスには、スライスを操作するための組み込みメソッドがいくつか用意されています。例えば:

  • len:スライスの長さを取得する。
  • ptr:スライスのポインタを取得する。
  • capacity:スライスの容量を取得します。つまり、それが参照できる配列部分の最大長です。

实例

const std = @import("std");

pub fn main() void {
    var arr: [5]i32 = [5]i32{ 1, 2, 3, 4, 5 };

    // 配列からスライスを作成
    const slice: []i32 = arr[1..4];

    // 通过索引访问切片元素
    std.debug.print("First element of slice: {}\n", .{slice[0]});
    std.debug.print("Second element of slice: {}\n", .{slice[1]});

    // スライスの長さ
    const length: usize = slice.len;
    std.debug.print("Slice length: {}\n", .{length});
}

コンパイル出力結果は:

First element of slice: 2
Second element of slice: 3
Slice length: 3

遍历切片

配列と同様に、使用できます。forスライスをループで走査する。

实例

const std = @import("std");

pub fn main() void {
    var arr: [5]i32 = [5]i32{ 1, 2, 3, 4, 5 };
    const slice: []i32 = arr[1..4];
    var index: usize = 1;

    // 遍历切片
    for (slice) |item| {
        std.debug.print("Index: {}, Item: {}\n", .{ index, item });
        index += 1;
    }
}

コンパイル出力結果は:

Index: 1, Item: 2
Index: 2, Item: 3
Index: 3, Item: 4

配列とスライスの違い

  • 大小:配列のサイズは固定されており、定義時に決定されます;スライスのサイズは動的に調整できます。
  • 存储位置:配列は通常スタック上に格納されますが、スライスが参照するメモリはヒープ上に置くことができます。
  • 灵活性:スライスはより柔軟で、配列の一部や動的に割り当てられたメモリを参照できます。
特性数组切片
大小固定され、コンパイル時に決定されます。動的で、サイズを変更できます。
元素类型相同相同
内存位置通常はスタック上にあります(ローカル変数)。参照されるメモリはヒープ上またはスタック上にある可能性があります。
访问通过索引スライスの開始インデックスと終了インデックスを使用します。
创建直接定义配列または他のスライスから作成されます。

以下の例では、printArray関数は固定サイズの配列を引数として受け取り、printSlice関数はスライスを引数として受け取ります。これらの関数を通じて、配列とスライスの受け渡しと使用の違いを確認できます。

实例

const std = @import("std");

fn printArray(arr: [5]i32) void {
    for (arr) |item| {
        std.debug.print("Array item: {}\n", .{item});
    }
}

fn printSlice(slice: []const i32) void {
    for (slice) |item| {
        std.debug.print("Slice item: {}\n", .{item});
    }
}

pub fn main() void {
    const arr: [5]i32 = [5]i32{ 1, 2, 3, 4, 5 };
    const slice: []const i32 = arr[1..4];

    printArray(arr);
    printSlice(slice);
}

コンパイル出力結果は:

Array item: 1
Array item: 2
Array item: 3
Array item: 4
Array item: 5
Slice item: 2
Slice item: 3
Slice item: 4
其他扩展