Генерация кода времени компиляции в D
в настоящее время я изучаю D, и одна из вещей, о которых я задавался вопросом, заключается в том, имеет ли D способ дублирования возможностей генерации кода языков JVM.
вот сценарий: У меня есть объект, и я хочу создать строку на основе этого объекта, который дает его имя и все его поля. В Java/Scala, Я может просто используйте отражение, но предположим, что скорость является проблемой. Я мог бы использовать библиотеку генерации байт-кода для динамического создания и компиляции класса, который это без размышлений. Реализация будет разбита на итерацию по полям объекта и получение его имени через рекурсию и использование этой информации для динамического создания Java (или байт-кода), который обращается к полям напрямую.
Если вам не нравится этот сценарий, потому что он слабый и/или нереалистичный, другой, который может быть более реалистичным, - это оптимизированная сериализация объектов.
Я видел примеры, когда оценка времени компиляции D и / или метапрограммирование шаблонов используется для таких вещей, как предварительное вычисление последовательности Фибоначчи во время компиляции и других рекурсивных алгоритмов, но есть ли способ сделать такие вещи только с языком и компилятором, или вам нужно разработать отдельный генератор кода и запустить его перед компилятором, чтобы получить такую функциональность?
2 ответов
String mixins может получить доступ к пространству имен, в которое они смешаны. Это включает this.tupleof
, который может использоваться для перебора полей класса. Шаблон сериализации может воспользоваться этим, или иным образом заставить пользователя указать поля для сериализации вручную, т. е.. class Class : ISerializable { int foo; Forble bar; mixin(genSerialize("foo, bar")); ... }
Это не только можно сделать, это практически сделано для вас в D2. Все, что вам нужно, это небольшой миксин, чтобы превратить их из функций времени компиляции в функции времени выполнения.
"имя класса", все, что вам нужно сделать, это оценить
typeof(this).stringof
в области видимости класса.для списка всех полей попробуйте
__traits(allMembers, typeof(this))
а затем отфильтровать материал, который не является полем (std.traits
будет полезно здесь).