#arrays #multidimensional-array #zig
#массивы #многомерный массив #зиг
Вопрос:
Я пишу функцию в 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?
Ответ №1:
Ваш 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
amp;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)
.
Другим подходом было бы использовать одномерный массив / буфер и соответствующим образом индексировать его, но это не совсем отвечает на ваш вопрос. Я довольно новичок в языке, поэтому могут быть тонкости, которые я пропустил.
Комментарии:
1. Рад помочь, я все еще играю с Zig сам, поэтому не могу обещать, что это лучший способ сделать это = D