2015-04-11 5 views
1

Возможно ли заполнить массив или ассоциативный массив неизменяемых объектов во время выполнения в D? У меня есть набор неизменных определений, данные которых считываются из внешнего источника во время выполнения. Каждое определение также содержит массивы нескольких других неизменяемых объектов. Однако, похоже, компилятор запрещает создавать неизменяемые массивы с использованием петель. В этом примере (поле данные упрощенно):Заполнение массива/вспомогательного массива неизменяемых объектов во время выполнения

immutable class Definition { 
    string name; 
    int size; 
    immutable(Field)[string] fields; 

    immutable class Field { 
     int num; 
     this (int num) { 
      this.num = num; 
     } 
    } 
    this(string name, int size) { 
     this.name = name; 
     this.size = size; 
     foreach (i; 0..size) { 
      string key = [cast(char)('a' + i)]; // a, b, c... 
      auto field = new immutable(Field)(i); 
      fields[key] = field; // ERROR 
     } 
    } 
} 
class Instance { 
    Definition def; 
    void speak() { 
     writefln("I am currently referencing definition '%s' (%d)", def.name, def.size); 
    } 
} 

auto defA = new immutable(Definition)("AAA", 4); 
auto defB = new immutable(Definition)("BBB", 6); 
auto instance = new Instance(); 
instance.def = cast(Definition) defA; 
instance.speak(); 
instance.def = cast(Definition) defB; 
instance.speak(); 

Я получаю Ошибки: инициализация неизменяемого поля «поле» не допускаются в петлях или после того, как этикетки. Есть ли способ обойти это или лучше сделать это? Или я об этом ошибаюсь?

ответ

4

Вам понадобится вспомогательная функция и временная.

--- test.d 2015-04-11 12:03:54.257670300 +0000 
+++ test2.d 2015-04-11 12:03:59.433170300 +0000 
@@ -1,3 +1,4 @@ 
+import std.exception; 
import std.stdio; 

immutable class Definition { 
@@ -14,11 +15,13 @@ 
    this(string name, int size) { 
     this.name = name; 
     this.size = size; 
+  immutable(Field)[string] fields; 
     foreach (i; 0..size) { 
      string key = [cast(char)('a' + i)]; // a, b, c... 
      auto field = new immutable(Field)(i); 
-   fields[key] = field; // ERROR 
+   add(fields, key, field); 
     } 
+  this.fields = fields.assumeUnique(); 
    } 
} 
class Instance { 
@@ -38,3 +41,9 @@ 
    instance.def = cast(Definition) defB; 
    instance.speak(); 
} 
+ 
+void add(K, V)(V[K] aa, K k, V v) 
+{ 
+ assert(k !in aa); 
+ cast()aa[k] = cast()v; 
+} 
+0

Это именно то, что я хотел, спасибо! – ccjuju

Смежные вопросы