【问题标题】:Filling an array/assoc array of immutable objects at runtime在运行时填充不可变对象的数组/关联数组
【发布时间】:2015-04-11 11:53:13
【问题描述】:

是否可以在运行时在 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();

我收到错误:循环中或标签后不允许不可变字段“字段”初始化。有没有办法解决这个问题,或者有更好的方法来完成它?还是我走错了路?

【问题讨论】:

    标签: immutability d


    【解决方案1】:

    您需要使用辅助函数和临时函数。

    --- 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;
    +}
    

    【讨论】:

      猜你喜欢
      • 2013-03-10
      • 2018-11-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-24
      • 2016-01-19
      • 2022-08-02
      相关资源
      最近更新 更多