Это просто, но приводит к некоторым потенциальным проблемам. Во-первых, нам нужно кое-что разобраться: хотим ли мы загрузить дерево объектов из файла или проанализировать его во время выполнения?
В 99% случаев людям достаточно синтаксического анализа static ref
при загрузке, поэтому я дам вам это решение; В конце я укажу вам на «другую» версию, но она требует много дополнительной работы и зависит от предметной области.
Макрос (потому что это должен быть макрос), который вы ищете для включения файла во время компиляции, находится в стандартной библиотеке: _ 2_. Как следует из названия, он берет ваш файл во время компиляции и генерирует из него &'static str
для использования. После этого вы можете делать с ним все, что захотите (например, анализировать).
Оттуда легко использовать lazy_static!
для создания static ref
для наш JSON Value
(или что бы вы там ни выбрали) для каждой части программы. В вашем случае, например, это могло бы выглядеть так:
const GAME_JSON: &str = include_str!("my/file.json");
#[derive(Serialize, Deserialize, Debug)]
struct Game {
name: String,
}
lazy_static! {
static ref GAMES: Vec<Game> = serde_json::from_str(&GAME_JSON).unwrap();
}
При этом нужно помнить о двух вещах:
- Это значительно приведет к увеличению размера вашего файла, поскольку
&str
никоим образом не сжимается. Рассмотрим gzip
- Вам нужно будет беспокоиться об обычных проблемах, связанных с многопоточным доступом к одному и тому же
static ref
, но, поскольку он не изменяемый, вам действительно нужно беспокоиться только о его части.
Другой способ требует динамической генерации ваших объектов во время компиляции с использованием процедурного макроса. Как уже говорилось, я бы не рекомендовал его, если у вас действительно нет действительно высоких начальных затрат при синтаксическом анализе этого JSON; большинство людей этого не сделает, и в последний раз у меня это было, когда я имел дело с глубоко вложенными файлами JSON размером в несколько ГБ.
Крейты, на которые вы хотите обратить внимание, - это proc_macro2
и syn
для генерации кода; остальное очень похоже на то, как вы бы написали обычный метод.
person
Sébastien Renauld
schedule
12.10.2019
include_bytes!
вместо _ 2_? - person Nils André   schedule 13.10.2019