1

我正在 Zig 中试验 n 维数组。

const expectEqual = std.testing.expectEqual;

fn NdArray(comptime n: comptime_int, comptime shape: [n]comptime_int) type {
    if (shape.len == 0) {
        // zero dimensional array, return the scalar type
        return u8;
    } else {
        return struct {
            // positive dimensional array, return an array of arrays one dimension lower
            data: [shape[0]]NdArray(n - 1, shape[1..].*)
        };
    }
}

test "NdArray test" {
    const expected = struct {
        data: [2]struct {
            data: [6]struct {
                data: [9]struct {
                    data: u8
                }
            }
        }
    };
    expectEqual(NdArray(3, [3]comptime_int{ 2, 6, 9 }), expected);
}

但我得到一个编译错误:

11:25: error: accessing a zero length array is not allowed
            data: [shape[0]]NdArray(n - 1, shape[1..].*)
                        ^

shape当长度为零时,我看不到编译器到达第 11 行的任何方法。编译器是否只是禁止索引shape,因为它没有整数文字表示的长度?

4

1 回答 1

1

更多的扩展评论而不是答案,我认为正如tuket所说,这似乎与编译器有关。我期待一个比我要给出的更好的解释 =D

看起来struct子作用域(如果这里适用这种情况)是在外部作用域之前评估的。shape[0]如果您将引用转移到父范围,它似乎有效:

fn NdArray(comptime n: comptime_int, comptime shape: [n]comptime_int) type {
    if (shape.len == 0) {
        // zero dimensional array, return the scalar type
        return u8;
    } else {
        var foo = shape[0];
        return struct {
        // positive dimensional array, return an array of arrays one dimension lower
            data: [foo]NdArray(n - 1, shape[1..].*)
        };
    }
}

由于您的错误将来自此递归的最后一次传递,因此另一种选择是以非递归方式重写它。

于 2020-10-17T14:45:00.227 回答