Согласно D Language Reference статическая инициализация ассоциативных массивов ассоциативный массив (AA) может быть инициализирован следующим образом:
immutable long[string] aa = [
"foo": 5,
"bar": 10,
"baz": 2000
];
void main()
{
import std.stdio : writefln;
writefln("(aa = %s)", aa);
}
Однако пример не компилируется с разумнымнедавний DMD:
$ dmd --version
DMD64 D Compiler v2.083.0
Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved written by Walter Bright
$ dmd -de -w so_003.d
so_003.d(3): Error: non-constant expression ["foo":5L, "bar":10L, "baz":2000L]
Небольшое прибегание к поиску указывает, что это давняя ошибка (?) в языке:
Так что я знаю, как обойти это с помощью статического конструктора .Однако, учитывая, что проблема существует уже около 10 лет, на практике это превратилось в функцию?
На самом деле это всего лишь прелюдия к моему актуальному вопросу:
Можно ли инициализироватьассоциативный массив во время компиляции?
В примере ниже я могу инициализировать уровень модуля string[] doubleUnits
с функцией генератора, которая выполняется во время компиляции (с CTFE ) какпроверено pragma(msg)
.И я могу инициализировать int[string] doubleUnitMap
во время выполнения.Но как я могу инициализировать AA во время компиляции?
import std.stdio : writefln;
immutable char[] units = ['a', 'b', 'c'];
immutable string[] doubleUnits = generateDoubleUnits(units);
pragma(msg, "compile time: ", doubleUnits);
string[] generateDoubleUnits(immutable char[] units)
pure
{
import std.format : format;
string[] buffer;
foreach(unit; units) {
buffer ~= format("%s%s", unit, unit);
}
return buffer;
}
immutable int[string] doubleUnitMap;
// pragma(msg) below triggers the following compilation error:
// Error: static variable doubleUnitMap cannot be read at compile time
// while evaluating pragma(msg, "compile time: ", doubleUnitMap)
// pragma(msg, "compile time: ", doubleUnitMap);
shared static this() {
doubleUnitMap = generateDoubleUnitMap(units);
}
int[string] generateDoubleUnitMap(immutable char[] units)
pure
{
import std.format : format;
int[string] buffer;
foreach(unit; units) {
string key = format("%s%s", unit, unit);
buffer[key] = 1;
}
return buffer;
}
void main()
{
writefln("(doubleUnits = %s)", doubleUnits);
writefln("(doubleUnitMap = %s)", doubleUnitMap);
}