如何创建任意大小的多维数组?
How can I create multidimensional arrays of arbitrary sizes?
我正在用 Zig 编写一个函数,它应该接受任意大小的多维数组。可能会有限制,但我无法提前对尺寸进行硬编码。
这是一个例子:
const warn = @import("std").debug.warn;
fn printMap(map: []const [4]bool) void {
for (map) |row| {
for (row) |tile| {
warn("{}\t", .{tile});
}
warn("\n", .{});
}
}
pub fn main() !void {
const map = [_][4]bool{
[_]bool{ false, false, false, false },
[_]bool{ false, true, true, false },
[_]bool{ false, true, true, false },
[_]bool{ false, false, false, false },
};
printMap(map[0..]);
}
这会编译并运行,但是如果我将函数签名更改为
fn printMap(map: []const []bool) void
我收到错误
expected type '[]const []bool', found '[]const [4]bool'
这可以用 Zig 表达吗?
你的map
被声明为多维数组[4][4]bool
,数组的长度是编译时类型的一部分(基于我对https://ziglang.org/documentation/master/#Slices的理解)。
正如您从 printMap
中了解到的那样,如果您希望在运行时定义这些大小,则必须使用切片(具有指针和长度的类型),例如[][]bool
要让您的示例使用签名 printMap(map: []const []bool)
,您可以执行以下操作:
var a = [_]bool{ false, false, true };
var b = [_]bool{ false, true, false };
const map = [_][]bool{
a[0..], // Make it a slice using slice syntax
&b, // Or make it a slice by coercing *[N]T to []T
};
var c: []const []bool = map[0..]; // Pass it as a slice of slices
printMap(c);
要创建任意大小的多维切片数组,您需要有一些缓冲区来存储数据。
您可以使用一些静态内存,或根据需要分配一些内存,一种方法可能是:
fn buildMap(x: u8, y: u8, allocator: *std.mem.Allocator) ![][]bool {
var map: [][]bool = undefined;
map = try allocator.alloc([]bool, x);
for (map) |*row| {
row.* = try allocator.alloc(bool, y);
}
return map;
}
哪个应该与 printMap(map: []const []bool)
一起使用。
另一种方法是使用单维 array/buffer,并适当地对其进行索引,但这并不能完全回答您的问题。我对这门语言还很陌生,所以我可能遗漏了一些细微之处。
我正在用 Zig 编写一个函数,它应该接受任意大小的多维数组。可能会有限制,但我无法提前对尺寸进行硬编码。
这是一个例子:
const warn = @import("std").debug.warn;
fn printMap(map: []const [4]bool) void {
for (map) |row| {
for (row) |tile| {
warn("{}\t", .{tile});
}
warn("\n", .{});
}
}
pub fn main() !void {
const map = [_][4]bool{
[_]bool{ false, false, false, false },
[_]bool{ false, true, true, false },
[_]bool{ false, true, true, false },
[_]bool{ false, false, false, false },
};
printMap(map[0..]);
}
这会编译并运行,但是如果我将函数签名更改为
fn printMap(map: []const []bool) void
我收到错误
expected type '[]const []bool', found '[]const [4]bool'
这可以用 Zig 表达吗?
你的map
被声明为多维数组[4][4]bool
,数组的长度是编译时类型的一部分(基于我对https://ziglang.org/documentation/master/#Slices的理解)。
正如您从 printMap
中了解到的那样,如果您希望在运行时定义这些大小,则必须使用切片(具有指针和长度的类型),例如[][]bool
要让您的示例使用签名 printMap(map: []const []bool)
,您可以执行以下操作:
var a = [_]bool{ false, false, true };
var b = [_]bool{ false, true, false };
const map = [_][]bool{
a[0..], // Make it a slice using slice syntax
&b, // Or make it a slice by coercing *[N]T to []T
};
var c: []const []bool = map[0..]; // Pass it as a slice of slices
printMap(c);
要创建任意大小的多维切片数组,您需要有一些缓冲区来存储数据。 您可以使用一些静态内存,或根据需要分配一些内存,一种方法可能是:
fn buildMap(x: u8, y: u8, allocator: *std.mem.Allocator) ![][]bool {
var map: [][]bool = undefined;
map = try allocator.alloc([]bool, x);
for (map) |*row| {
row.* = try allocator.alloc(bool, y);
}
return map;
}
哪个应该与 printMap(map: []const []bool)
一起使用。
另一种方法是使用单维 array/buffer,并适当地对其进行索引,但这并不能完全回答您的问题。我对这门语言还很陌生,所以我可能遗漏了一些细微之处。