创建具有静态生命周期的匿名变量时的最佳做法是什么?

What are best practices when creating an anonymous variable with static lifetime?

这是一个由两部分组成的问题:(1) 传递高阶函数静态引用以使它们(参数)足够长的时间是否是一种好习惯? (2) 创建具有静态生命周期的匿名变量的最佳方法是什么?

这是上下文:我有一个元函数,returns 一个基于其参数的闭包。为了确保参数的寿命足够长,它们必须是静态引用。例如,

pub enum Uncloneable { Variant }

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

但我不想每次调用 get_getter 时都用大量 const 定义来弄乱我的代码,例如

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));
}

效果很好,但我担心我可能会在这里重新发明轮子(甚至犯下一些反模式)。

Here's he full code on Rust Playground.

我不认为你的宏是反模式,但在这种情况下它不一定很有用。 const 不为该值分配任何存储空间,它只是在编译时进行替换,因此您的代码与以下内容相同:

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

换句话说,用const来存储值没有必要也没有什么不同。

此外,引用自动升级为 &'static UncloneableRust reference explains:

When using a value expression in most place expression contexts, a temporary unnamed memory location is created initialized to that value and the expression evaluates to that location instead, except if promoted to 'static. Promotion of a value expression to a 'static slot occurs when the expression could be written in a constant, borrowed, and dereferencing that borrow where the expression was originally written, without changing the runtime behavior. That is, the promoted expression can be evaluated at compile-time and the resulting value does not contain interior mutability or destructors (these properties are determined based on the value where possible, e.g. &None always has the type &'static Option<_>, as it contains nothing disallowed).

所以本质上,如果你可以像你的代码一样使用常量,你也可以直接引用该值,如果可以的话,它会自动提升为 'static 引用。