Каковы лучшие практики при создании анонимной переменной со временем жизни stati c? - PullRequest
1 голос
/ 09 апреля 2020

Это вопрос, состоящий из двух частей: (1) Является ли хорошей практикой передача функций высшего порядка в состояние c, чтобы они (параметры) жили достаточно долго? (2) Каков наилучший способ создать анонимную переменную с stati c продолжительностью жизни?

Вот контекст: у меня есть мета-функция, которая возвращает замыкание на основе его параметров. Для того, чтобы параметры жили достаточно долго, они должны быть c ссылками. Например,

pub enum Uncloneable { Variant }

pub fn get_getter(param:&'static Uncloneable)
                  -> Box<dyn Fn() -> &'static Uncloneable> {
    Box::new(move || { param })
}

Но я не хочу загромождать мой код множеством const определений каждый раз, когда я вызываю get_getter, например,

fn main() {
    let _result = get_getter({
        const VAR:Uncloneable = Uncloneable::Variant;
        &VAR
    });
}

Мое текущее решение - использовать макрос:

#[macro_export]
macro_rules! staticify {
    ($type:tt :: $variant:tt) => {{
        const VAR:$type = $type::$variant;
        &VAR
    }};
}

fn main() {
    let _result = get_getter(staticify!(Uncloneable::Variant));
}

, который прекрасно работает, но я боюсь, что я могу заново изобрести колесо (или даже применить какой-нибудь анти-шаблон).

Вот Полный код на Rust Playground.

1 Ответ

2 голосов
/ 09 апреля 2020

Я не думаю, что ваш макрос является антипаттерном, но он не обязательно очень полезен в этом случае. const не выделяет хранилище для значения, оно просто выполняет подстановку во время компиляции, поэтому ваш код такой же, как и просто:

fn main() {
    let _result = get_getter(&Uncloneable::Variant);
}

Другими словами, он не нужен и не отличается от использования const для хранения значения.

Кроме того, ссылка автоматически повышается до &'static Uncloneable. Ссылка Rust объясняет :

При использовании выражения значения в большинстве контекстов выражения места создается временная безымянная ячейка памяти, инициализированная для этого значения, и выражение вместо этого оценивается в этом расположении За исключением случаев повышения до 'static. Преобразование выражения значения в слот 'static происходит, когда выражение может быть записано в константе, заимствовано и разыменовано, что заимствует место, где выражение было изначально записано, без изменения поведения во время выполнения. То есть продвигаемое выражение может быть оценено во время компиляции, и результирующее значение не содержит внутреннюю изменчивость или деструкторы (эти свойства определяются на основе значения, где это возможно, например, &None всегда имеет тип &'static Option<_>, поскольку оно не содержит ничего запрещенного ).

По сути, если вы можете использовать константу, подобную вашему коду, вы также можете просто взять ссылку на это значение напрямую, и она будет автоматически преобразована в ссылку 'static, если она может быть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...