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