c0d*_*1ne 5 static constants path rust
我正在开发 CLI 来进行学习。这个 CLI 涉及一个文件系统,我想在“文件系统”模块中声明一些公共和静态(或常量) Path 对象,以便板条箱中的其他模块可以在需要时使用它们。
我无法以一种满足我学究气的方式来宣布这些。我知道这是可以通过一些惰性求值技术来实现的,但这会将数据存储在堆上......鉴于路径在编译时已知,我根本不明白为什么我们不能将其存储为静态或常量值。
我确实理解Path::new 方法应该定义为pub **const** fn new()使其工作,但鉴于情况并非如此并且编译器建议使用Lazy::new(|| ...),我想即使路径是硬编码的,也无法对其进行评估是有原因的在编译时使用 static 或 const ...
请注意,我并不是在寻找涉及将路径存储为字符串或堆上的解决方法,而是寻找一种实现我想要的方法或解释为什么它无法实现的方法。
下面是一个片段,可以更好地说明我想要实现的目标,与编译器错误相关:
use std::path::Path;
static ROOT_DIR: &Path = Path::new("/myproject");
// static LOGS_DIR: &Path = ROOT_DIR.join("logs").as_path();
fn main() {
    println!("{}", ROOT_DIR.display());
    // println!("{}", LOGS_DIR.display());
}
error[E0015]: cannot call non-const fn `Path::new::<str>` in statics
 --> src/main.rs:4:26
  |
4 | static ROOT_DIR: &Path = Path::new("/myproject");
  |                          ^^^^^^^^^^^^^^^^^^^^^^^
  |
  = note: calls in statics are limited to constant functions, tuple structs and tuple variants
  = note: consider wrapping this expression in `Lazy::new(|| ...)` from the `once_cell` crate: https://crates.io/crates/once_cell
For more information about this error, try `rustc --explain E0015`.
error: could not compile `shaka` due to previous error
不幸的是,目前这是不可能的,即使是在夜间也是如此。
原因是因为Path::new()被定义为泛型方法。Path::new(str)只是另一种说法str.as_ref().as_ref()(调用AsRef::as_ref(),首先转换为OsStr( impl AsRef<OsStr> for str),然后将其转换为Path( impl AsRef<Path> for OsStr),只是更清晰,更适合推理。Path::new()接受实现 的所有内容AsRef<OsStr>。
为了巩固这一点,我们必须巩固AsRef实施并限制AsRef为const。目前这只能在每晚进行,但存在重大设计问题。所以我们不可能不让Path::new()const稳定。
有一个开放的 PR 用于添加可以执行 const-way 的方法,但它没有合并,并且不清楚我们是否要提交此解决方法。