我应该如何初始化这个多维数组?

6

我有一个巨大的三维数组,它代表了我的世界。它太大了,无法静态初始化:

alias Cell[128][128][128] World; // <-- The compiler points to this line

Error: index 128 overflow for static array

我尝试使用World* world,但仍会出现上面的溢出错误。所以我现在有的是这个丑陋的混乱代码:

alias Cell[][][] World;
// ...
private World world;
// ...
world.length = WORLD_XDIM;
for (uint x = 0; x < world.length; ++x)
{
    world[x].length = WORLD_YDIM;
    for (uint y = 0; y < world[x].length; ++y)
    {
        world[x][y].length = WORLD_ZDIM;
    }
}

这种方式是可行的,但它让我内心有点难过。有没有一种方法可以将 calloc 的结果转换为三维数组?我已经使用过对常规数组进行分片的方法来实现了,但三维数组让我很困惑。


1
这是第666个标记为[d]的问题。嗯。 - nmichaels
这是关于我最喜欢的D语言主题,多维数组的定义/初始化。我仍然不理解其语义。 - sleeplessnerd
1个回答

9

如果你想声明一个交错数组(即每个子数组的长度可能不同),那么你需要像你现在这样使用循环,但对于一致的数组来说,这是不必要的。以下是如何初始化一个不是交错的多维数组:

auto arr = new Cell[][][](128, 128, 128);

当您将数字放在括号之间时,您正在创建一个静态数组的动态数组。因此,
auto arr = new Cell[128][128][128];

声明一个长度为128的静态数组的动态数组,其中每个元素都是长度为128的静态数组。我猜如果你确实需要这样做(而我从未需要过),那么它可能会很有用,但它绝对会经常让新手犯错。
个人而言,为了完全避免这种问题,即使在声明单维数组时,我也从不在括号中加入数字:
auto arr = new Cell[](128);

我认为在第一个维度的方括号内放置数字被视为动态数组,而在任何进一步的级别中放置数字被视为静态数组是一个糟糕的设计选择,我不知道为什么会这样,但它确实是这样。我可以理解想要创建静态数组的动态数组,但更加一致的做法要么是禁止使用 new Cell[128],要么是返回长度为 128 的 Cell[]Cell[128]*,但不幸的是,它并不是这样工作的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接