哨兵终止数组的 Zig 切片,不包括所有尾随哨兵

问题描述 投票:0回答:1

给定一个哨兵终止的数组

[N:0]T
,它仅在数组的开头部分填充了未知数量的实体
n < N
,其余部分则填充了哨兵(
0
),最简洁的方法是什么抓取一个只包含任何哨兵之前的第一个实体的切片?

这是 Linux 中的代码示例,其中

utsname.release: [64:0]u8
由操作系统使用内核的语义版本字符串填充。

const std = @import("std");

// ...

    const utsname: std.os.linux.utsname = std.os.uname();
    std.debug.print("utsname.release = '{s}'\n", .{utsname.release});
    std.debug.print("utsname.release.len = {}\n", .{utsname.release.len});
    const utsNameReleaseSlice: []const u8 = &utsname.release;
    std.debug.print("utsNameReleaseSlice = '{s}'\n", .{utsNameReleaseSlice});
    std.debug.print("utsNameReleaseSlice.len = {}\n", .{utsNameReleaseSlice.len});

输出:

utsname.release = '6.6.8-gnu'
utsname.release.len = 64
utsNameReleaseSlice = '6.6.8-gnu'
utsNameReleaseSlice.len = 64

在上面的打印中,字符串看起来不错,但它打印出零宽度字符的标记。当我将切片提供给

std.SemanticVersion.parse
时,它在到达那些哨兵字符时会抛出错误。

为了解决这个问题,我获取了第一个哨兵的索引,并在那里进行了切片:

    const versionStringEnd: usize = std.mem.indexOf(u8, &utsname.release, &[_]u8{0}) orelse utsname.release.len;
    const utsNameReleaseSlice: []const u8 = utsname.release[0..versionStringEnd];
    std.debug.print("utsNameReleaseSlice = '{s}'\n", .{utsNameReleaseSlice});
    std.debug.print("utsNameReleaseSlice.len = {}\n", .{utsNameReleaseSlice.len});

输出:

utsNameReleaseSlice = '6.6.8-gnu'
utsNameReleaseSlice.len = 9

有没有更简洁的方法来获取这个忽略哨兵的切片?

arrays slice sentinel zig
1个回答
0
投票

您正在寻找

std.mem.span
,它正是这样做的。

© www.soinside.com 2019 - 2024. All rights reserved.