Zig-Arrays und Slices

In der Programmiersprache Zig sind Arrays und Slices grundlegende Strukturen zum Speichern und Manipulieren einer Menge von Daten desselben Typs.

  • Array: Dient zum Speichern einer festen Anzahl von Daten desselben Typs, wobei die Größe bei der Definition angegeben und auf dem Stack gespeichert wird.
  • Slice: Wird verwendet, um auf einen Teil eines Arrays oder einen anderen zusammenhängenden Speicherbereich zu verweisen. Seine Größe kann dynamisch angepasst werden, was ihn flexibler macht, und er verweist normalerweise auf Heap-Speicher.

Array:

  • Ein Array ist eine Sequenz fester Länge, deren Größe zur Kompilierzeit bestimmt wird.
  • Der Typ eines Arrays ist[T], wobeiTist der Typ der Elemente im Array.
  • Der Speicher von Arrays ist zusammenhängend, was ihnen einen Leistungsvorteil verschafft, insbesondere bei der Verarbeitung großer Datenmengen.

Slice:

  • Ein Slice ist eine dynamisch dimensionierte Sequenz, deren Größe zur Laufzeit geändert werden kann.
  • Der Typ eines Slices ist[]T, wobeiTist der Typ der Elemente im Slice.
  • Ein Slice ist tatsächlich eine Referenz auf ein Array; es enthält einen Zeiger auf das Array und die Länge des Slices.
  • Slices können flexibler mit Daten umgehen, da sie leicht geteilt und zwischen verschiedenen Arrays übergeben werden können.

Array

Arrays haben eine feste Größe, werden auf dem Stack gespeichert, und die Elementtypen müssen identisch sein.

Sie können die[]Syntax verwenden, um ein Array zu definieren und seine Größe anzugeben.

Der Typ eines Arrays wird als[T; N]definiert, wobei T der Typ der Array-Elemente und N die Länge des Arrays ist.

Auf Array-Elemente kann über den Index zugegriffen werden, wobei die Indizierung beginnt bei00.

Syntax

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

Parameter description:

  • arrayName: Der Name des Arrays.
  • size: Die Größe des Arrays (Anzahl der Elemente), die eine Konstante zur Kompilierzeit ist.
  • ElementType: Der Typ der Elemente im Array.
  • element1, element2, ...: Die Elemente im Array.

Ein Array ist ein zusammenhängender Speicherblock fester Größe, dessen Größe zur Kompilierzeit bestimmt wird:

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

Beispiel

const std = @import("std");

pub fn main() void {
    // Definiere ein Array mit 5 Elementen vom Typ i32
    const arr: [5]i32 = [5]i32{1, 2, 3, 4, 5};

    // Zugriff auf Array-Elemente über den Index
    std.debug.print("Erstes Element: {}\n", .{arr[0]});
    std.debug.print("Drittes Element: {}\n", .{arr[2]});

    // Die Größe des Arrays ist fest
    const size: usize = arr.len;
    std.debug.print("Array size: {}\n", .{size});
}

Die Kompilierungsausgabe ist:

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

Über ein Array iterieren

Sie können einefor-Schleife verwenden, um über die Elemente eines Arrays zu iterieren.

Beispiel

const std = @import("std");

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

    var index: usize = 0;

    // Über das Array iterieren
    for (arr) |item| {
        std.debug.print("Index: {}, Item: {}\n", .{ index, item });
        index += 1;
    }
}

Die Kompilierungsausgabe ist:

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

Slice

Ein Slice ist eine Referenz auf einen Teil eines Arrays oder einen anderen zusammenhängenden Speicherbereich.

Ein Slice kann seine Größe dynamisch anpassen und ist flexibler als ein Array, aber seine Elemente werden auf dem Heap gespeichert.

Definition und Initialisierung

Ein Slice ist eine Referenz auf einen Teil eines Arrays oder einen anderen zusammenhängenden Speicherbereich.

Ein Slice ist dynamisch und kann seine Größe ändern; er wird oft verwendet, um einen Teil eines Arrays oder einen dynamisch zugewiesenen Speicherblock darzustellen.

Syntax

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

Parameter description:

  • sliceName: Der Name des Slices.
  • ElementType: Der Typ der Elemente im Slice.
  • array[start..end]: Vonarrayeinen Teil-Slice extrahieren,startundendist der Index.

Ein Slice kann aus einer Teilmenge eines Arrays erstellt werden, oder er kann aus einem Zeiger und einer Länge erstellt werden:

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

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

Slices bieten einige integrierte Methoden zum Manipulieren von Slices, zum Beispiel:

  • len: Ruft die Länge des Slices ab.
  • ptr: Ruft den Zeiger des Slices ab.
  • capacity: Ruft die Kapazität des Slices ab, d. h. die maximale Länge des Array-Abschnitts, auf den er verweisen kann.

Beispiel

const std = @import("std");

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

    // Einen Slice aus einem Array erstellen
    const slice: []i32 = arr[1..4];

    // Zugriff auf Slice-Elemente über den Index
    std.debug.print("Erstes Element des Slices: {}\n", .{slice[0]});
    std.debug.print("Zweites Element des Slices: {}\n", .{slice[1]});

    // Die Länge des Slices
    const length: usize = slice.len;
    std.debug.print("Slice-Länge: {}\n", .{length});
}

Die Kompilierungsausgabe ist:

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

Über ein Slice iterieren

Ähnlich wie bei Arrays können Sie einefor-Schleife verwenden, um über das Slice zu iterieren.

Beispiel

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;

    // Über das Slice iterieren
    for (slice) |item| {
        std.debug.print("Index: {}, Item: {}\n", .{ index, item });
        index += 1;
    }
}

Die Kompilierungsausgabe ist:

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

Unterschiede zwischen Arrays und Slices

  • Größe: Die Größe eines Arrays ist fest und wird bei der Definition bestimmt; die Größe eines Slices kann dynamisch angepasst werden.
  • Speicherort: Arrays werden normalerweise auf dem Stack gespeichert, während der von einem Slice referenzierte Speicher auf dem Heap liegen kann.
  • Flexibilität: Slices sind flexibler und können einen Teil eines Arrays oder dynamisch zugewiesenen Speicher referenzieren.
MerkmalArraySlice
SizeFest, zur Kompilierzeit festgelegtDynamisch, Größe kann geändert werden
ElementtypGleichGleich
SpeicherortNormalerweise auf dem Stack (lokale Variablen)Referenzierter Speicher kann auf dem Heap oder auf dem Stack liegen
AccessÜber den IndexDurch die Start- und Endindizes des Slices
ErstellungDirekte DefinitionAus einem Array oder einem anderen Slice erstellt

Im folgenden Beispiel nimmt die Funktion printArray ein Array fester Größe als Parameter, während die Funktion printSlice ein Slice als Parameter nimmt. Anhand dieser Funktionen können Sie die Unterschiede zwischen Arrays und Slices bei der Übergabe und Verwendung sehen.

Beispiel

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);
}

Die Kompilierungsausgabe ist:

Array item: 1
Array item: 2
Array item: 3
Array item: 4
Array item: 5
Slice item: 2
Slice item: 3
Slice item: 4
Andere Erweiterungen