为什么 std::fs::write(...) 使用内部函数?

Cha*_*lle 62 file-io nested-function rust

我是 Rust 新手,浏览了一下源代码,发现了这个:

#[stable(feature = "fs_read_write_bytes", since = "1.26.0")]
pub fn write<P: AsRef<Path>, C: AsRef<[u8]>>(path: P, contents: C) -> io::Result<()> {
    fn inner(path: &Path, contents: &[u8]) -> io::Result<()> {
        File::create(path)?.write_all(contents)
    }
    inner(path.as_ref(), contents.as_ref())
}
Run Code Online (Sandbox Code Playgroud)

这个函数有什么理由定义这样的内部函数吗?为什么不直接写:

File::create(path.as_ref())?.write_all(contents.as_ref())
Run Code Online (Sandbox Code Playgroud)

Cha*_*man 72

单态化成本。

write()与 Rust 中的大多数文件系统函数一样,为了方便起见,使用,AsRef<Path>来代替Path(以允许您传递例如 a &str)。但这也是有代价的:这意味着该函数将针对每种类型单独进行单态化和优化,但实际上并没有必要这样做。虽然 LLVM 很可能会删除所有这些实例的重复数据,但用于优化它们的时间仍然浪费了编译时间。

为了减轻这种成本,它调用一个内部的非泛型函数来完成所有繁重的工作。外部函数仅包含必要的通用代码 - 转换为Path.

  • @TLW 嵌套函数不是闭包:它们无法访问外部函数的环境(参数[包括类型参数]和外部函数的局部变量)。因此,“inner”本身并不是一个通用函数。嵌套函数和非嵌套函数之间的主要区别在于,嵌套函数仅在外部函数的范围内。 (23认同)
  • 等待。泛型函数内定义的嵌套函数仅实例化一次?这是如何运作的? (7认同)
  • @TLW 嵌套函数尽管看起来位于父函数的范围内,但实际上无法访问它的泛型参数 (3认同)