欢迎您 本站地址:  

Zig 数组和切片

在 Zig 编程语言中,数组和切片(slice)是用于存储和操作一组相同类型数据的基本结构。

数组(Array):

切片(Slice):


数组

数组是固定大小的,存储在栈上,元素类型必须相同。

可以使用 [] 语法来定义数组,并指定数组的大小。

数组的类型定义为 [T; N],其中 T 是数组元素的类型,N 是数组的长度。

数组的元素可以通过索引访问,索引从 0 开始。

语法格式

const arrayName: [size]ElementType = [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];

参数说明:

切片可以通过数组的子集来创建,也可以通过指针和长度来创建:

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

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

切片提供了一些内置的方法来操作切片,例如:

实例

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
小库提示

扫描下方二维码,访问手机版。