Как создать динамический массив структур в D с отключенным конструктором в?

У меня есть такой код:

struct MyStruct {
    immutable int id;
    immutable int value;

    this() @disable;

    this(immutable int pId) {
        id = pId;
        value = getValueById(id);
    }
}

void main() {
    MyStruct structs = new MyStruct[](256); // No default initializer
    foreach(ulong id, MyStruct struct_; structs) {
        structs[id] = MyStruct(id); // Cannot edit immutable members
    }
}

Я знаю, что могу просто инициализировать динамический массив и добавить к нему, но мне интересно посмотреть, есть ли более эффективный способ сделать это. Я в основном обеспокоен тем, как ему придется перераспределять каждый раз, когда он действительно знает, сколько памяти ему нужно заранее.

1 ответ

Решение

Самое простое решение - использовать динамический массив и вызвать .reserve Метод, прежде чем делать какие-либо добавления. Тогда это будет предварительно распределять пространство, и будущие добавления будут дешевы.

void main() {
    MyStruct[] structs;
    structs.reserve(256); // prealloc memory
    foreach(id; 0 .. 256)
        structs ~= MyStruct(id); // won't reallocate
}

Вот как я бы сделал это с динамическими массивами, написав отдельным членам, я не думаю, что когда-либо будет работать с такой неизменностью.

Кстати, если вам нужен статический массив, вызов резерва не будет работать, но вы можете явно инициализировать его.... для void, Это оставит память совершенно случайной, но поскольку вы явно запросили ее, отключенный конструктор по умолчанию не остановит вас. (Кстати, это запрещено в @safe функции) Но в этом случае эти неизменные члены навсегда оставят его мусором, если вы не отбросите неизменность, чтобы подготовить его так... не очень реально, просто приятно узнать, понадобится ли вам это когда-нибудь в будущем.

Другие вопросы по тегам