Можно ли написать что-то более сложное, чем `print!`, В чистом макросе Rust? - PullRequest
0 голосов
/ 26 мая 2018

Я начинаю изучать макросы Rust, но документация несколько ограничена.Что хорошо - я полагаю, это экспертная особенность.Хотя я могу выполнять базовую генерацию кода, реализацию признаков и т. Д., Некоторые из встроенных макросов кажутся намного лучше, например, различные макросы печати, которые проверяют строковый литерал и используют его для расширения кода.

Я посмотрел на источник print!, и он вызывает другой макрос с именем format_args.К сожалению, это, кажется, не встроено в «чистый Rust», в комментарии просто говорится «встроенный компилятор».

Возможно ли написать что-то столь же сложное, как print! в чистом макросе Rust?Если так, как это будет сделано?

Я на самом деле заинтересован в построении "tree времени компиляции" - в основном распознавая определенные фиксированные строки как "ключевые слова", фиксированные во время компиляции.Это было бы производительно (вероятно), но в основном я просто заинтересован в генерации кода.

Ответы [ 2 ]

0 голосов
/ 27 мая 2018

format_args реализован в самом компиляторе, в ящике libsyntax_ext.Имя зарегистрировано в функции register_builtins , а код для его обработки имеет точку входа в функцию expand_format_args .

Макросы, которые делают это.детальная обработка синтаксиса не может быть определена с помощью конструкции macro_rules!.Они могут быть определены с помощью процедурного макроса ;однако эта функция в настоящее время нестабильна (может использоваться только с ночным компилятором и подвержена внезапным и необъявленным изменениям) и довольно редко документируется.

0 голосов
/ 26 мая 2018

Макросы Rust не могут анализировать строковые литералы, поэтому невозможно создать прямой эквивалент Rust format_args!.

Что вы можете сделать, это использовать макрос для преобразования синтаксиса, похожего на вызов функции, вчто-то, что каким-то образом представляет список переменных аргументов в системе типов Rust (скажем, как гетерогенный односвязный список или тип компоновщика).Затем его можно передать в обычную функцию Rust вместе со строкой форматирования.Но вы не сможете реализовать проверку типов строки формата во время компиляции таким способом.

...