具有任意常量表达式的 cfg 属性
cfg attribute with arbitrary constant expression
我有以下常量:
const IS_WSL: bool = is_wsl!();
我希望能够将其与 cfg
属性一起使用来执行条件编译。类似于:
#[cfg(const = "IS_WSL")] // what goes here?
const DOWNLOLADS: &'static str = "/mnt/c/Users/foo/Downloads";
#[cfg(not(const = "IS_WSL"))]
const DOWNLOADS: &'static str = "/home/foo/Downloads";
显然这个语法不起作用,但是有什么方法可以实现我所描述的吗?
我知道自定义 rustc 标志,但我想避免这样做,因为有相当多的逻辑我不想尝试在 bash
中编写
答案是否定的。您必须使用构建脚本之类的东西来实现。
它无法工作,因为 cfg
- 扩展发生在编译器中比常量评估更早的阶段。
cfg
扩展与宏扩展同时工作。两者都会影响名称解析(宏可以创建新名称,其他宏甚至同一个宏以后可以引用)这迫使我们使用 fixed-point 算法(解析名称、扩展宏、解析名称、扩展宏...直到无法解析更多名称,即达到固定点)。 const
评估在类型检查之后进行,有时(使用 generic_const_exprs
)甚至在代码生成期间。如果它能影响宏扩展,我们将有一个巨大的 fixed-point 循环解析名称 - 扩展宏 - 解析名称 - 扩展宏...直到达到固定点,然后降低到 HIR - type-check -评估常量(或什至低于 MIR - 单态化和评估常量) - 并返回名称解析。除了大大降低编译器速度外,它还会使编译器变得更加复杂,这并不是 rustc 团队真正想要的。
在您的特定情况下,由于两个 cfg
变体都声明了具有相同名称和类型的静态,您可以只匹配 IS_WSL
:
const IS_WSL: bool = is_wsl!();
const DOWNLOADS: &'static str = match IS_WSL {
true => "/mnt/c/Users/foo/Downloads",
false => "/home/foo/Downloads",
};
这与 cfg
的功能不同,但如果您只需要 select 两个相同类型的值,它仍然有用。
我有以下常量:
const IS_WSL: bool = is_wsl!();
我希望能够将其与 cfg
属性一起使用来执行条件编译。类似于:
#[cfg(const = "IS_WSL")] // what goes here?
const DOWNLOLADS: &'static str = "/mnt/c/Users/foo/Downloads";
#[cfg(not(const = "IS_WSL"))]
const DOWNLOADS: &'static str = "/home/foo/Downloads";
显然这个语法不起作用,但是有什么方法可以实现我所描述的吗?
我知道自定义 rustc 标志,但我想避免这样做,因为有相当多的逻辑我不想尝试在 bash
中编写答案是否定的。您必须使用构建脚本之类的东西来实现。
它无法工作,因为 cfg
- 扩展发生在编译器中比常量评估更早的阶段。
cfg
扩展与宏扩展同时工作。两者都会影响名称解析(宏可以创建新名称,其他宏甚至同一个宏以后可以引用)这迫使我们使用 fixed-point 算法(解析名称、扩展宏、解析名称、扩展宏...直到无法解析更多名称,即达到固定点)。 const
评估在类型检查之后进行,有时(使用 generic_const_exprs
)甚至在代码生成期间。如果它能影响宏扩展,我们将有一个巨大的 fixed-point 循环解析名称 - 扩展宏 - 解析名称 - 扩展宏...直到达到固定点,然后降低到 HIR - type-check -评估常量(或什至低于 MIR - 单态化和评估常量) - 并返回名称解析。除了大大降低编译器速度外,它还会使编译器变得更加复杂,这并不是 rustc 团队真正想要的。
在您的特定情况下,由于两个 cfg
变体都声明了具有相同名称和类型的静态,您可以只匹配 IS_WSL
:
const IS_WSL: bool = is_wsl!();
const DOWNLOADS: &'static str = match IS_WSL {
true => "/mnt/c/Users/foo/Downloads",
false => "/home/foo/Downloads",
};
这与 cfg
的功能不同,但如果您只需要 select 两个相同类型的值,它仍然有用。