D语言:初始化动态多维数组的最佳实践?

11

我只是好奇这是否是在D中初始化动态多维数组的最佳实践。虽然他们的语言参考手册中有一个关于数组的章节,但我不确定它是否涵盖了我试图完成的任务。

class Map {
    Tile[][] tiles;

    this(uint width, uint height) {
        tiles.length = height;
        foreach (ref tilerow; tiles)
            tilerow.length = width;
    }
}

Map map1 = new Map(5000, 3000); // values determined at runtime

(或者使用类似于典型的for (y=0;y<height;y++)循环的等效替代方案)。

我关注的是它逐行重新分配数组而不是一次性重新分配整个块,因此我不知道这是否会导致过多的内存移动。另外,我认为它不能保证是连续的(因为在这种情况下tiles只是指针的数组)。有没有更好的方法来做到这一点(不涉及使用单维数组并自己计算索引)?据我从文档中了解,一个连续的多维数组只能在编译时声明不可变的维度,只是想知道我是否遗漏了什么......

2个回答

18

在 D2 中,您可以使用 new 关键字创建数组:

Tile[][] tiles = new Tile[][](height, width);

我认为这是最佳实践。


2
从技术上讲,“最佳实践”是在左侧使用“auto”,而不是重复类型。但是,如果每个多维数组的长度都应该相同,那么这是分配多维数组的最佳方法。 - Jonathan M Davis
请参阅http://www.d-programming-language.org/expression.html#NewExpression。 - XP1

3

您可以通过预先使用 malloc 分配所需的所有内容来操纵它

this(uint width, uint height) {
    void* p = enforce(GC.malloc(Tile.sizeof*width*height),new OutOfMemoryException);
          //allocate all rows at once, throw on returned null
    tiles.length = height;
    foreach (i,ref tilerow; tiles)
        tilerow = cast(Tile[])p[Tile.sizeof*width*i..Tile.sizeof*width*(i+1)];
                //slice it into the multidimensional array
}

编辑或使用临时数组来保持它们的整洁性/更少的错误(即隐藏malloc)。

this(uint width, uint height) {
    Tile[] p = new Tile[height*width]
    tiles.length = height;
    foreach (i,ref tilerow; tiles)
        tilerow = p[width*i..width*(i+1)];
                //slice it into the multidimensional array
}

1
第一个示例的小提示:您可以使用enforceEx,例如enforceEx!OutOfMemoryError(GC.malloc(Tile.sizeof * width * height));,而且它不是OutOfMemoryException,而是OutOfMemoryError,这些需要导入到std.exceptioncore.memorycore.exception - Andrej Mitrović

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