【问题标题】:How to convert a generic function into a function pointer with a reference parameter?如何将泛型函数转换为带有引用参数的函数指针?
【发布时间】:2023-03-22 12:32:01
【问题描述】:
pub fn remove_file<P: AsRef<Path>>(path: P) -> Result<()>;

我正在努力将std::fs::remove_file 转换为函数指针: Playground

use std::{io, fs, path::Path};

fn main() {
    let _:  fn(&Path) -> io::Result<()> = &fs::remove_file;

    // let _: &dyn FnOnce(&Path) -> io::Result<()> = &fs::remove_file;
}

错误如下:

error[E0308]: mismatched types
 --> src/main.rs:4:43
  |
4 |     let _:  fn(&Path) -> io::Result<()> = &fs::remove_file;
  |             ---------------------------   ^^^^^^^^^^^^^^^^ expected fn pointer, found reference
  |             |
  |             expected due to this
  |
  = note: expected fn pointer `for<'r> fn(&'r std::path::Path) -> std::result::Result<(), std::io::Error>`
              found reference `&fn(_) -> std::result::Result<(), std::io::Error> {std::fs::remove_file::<_>}`

问题可能出在for&lt;'r&gt; 高阶生命周期要求上,但我不知道如何解决。

我将如何处理 trait 对象?以下内容也无法编译:

let _: &dyn FnOnce(&Path) -> io::Result<()> = &fs::remove_file;

我知道我可以围绕 fs::remove_file 创建一个包装函数,但我想避免这种情况并让 fs::remove_file 成为函数指针或特征对象本身。

这不是这个Function pointers in Rust using constrained generics 的副本,因为我想获得一个函数指针,指向std::fs::remove_file 的具体实例化,&amp;Path 作为类型参数,但不具有通用函数指针类型。

我尝试了以下方法,但它也不起作用:

use std::{io, fs, path::Path};

fn main() {
    let _:  fn(&Path) -> io::Result<()> = &fs::remove_file::<&Path>;
}

【问题讨论】:

  • 不,它没有回答这个问题,我已经为此添加了解释
  • 注意&amp;fs::remove_file是一个函数指针指针。你不需要&amp;
  • 是的,我也注意到了,但我尝试了多种变体,只是发布了最后一个变体......
  • 为什么要避免使用包装函数或闭包?没有包装器就不可能做到这一点,而且我真的看不出使用包装器的缺点。
  • 在这种情况下,您只需要|p| fs::remove_file(p),这真的不是冗长。如果没有包装器,您确实无法做到这一点 - 类型不兼容。

标签: rust function-pointers


【解决方案1】:

我想获得一个指向 std::fs::remove_file 的具体实例化的函数指针,其中 &amp;Path 作为类型参数,但没有通用函数指针类型。

这是问题的核心。将编译一个具体的实例化。例如:

let _ : fn(&'static Path) -> io::Result<()> = fs::remove_file::<&'static Path>;
let _ : fn(&'r Path) -> io::Result<()> = fs::remove_file::<&'r Path>;
let _ : fn(&'long Path) -> io::Result<()> = fs::remove_file::<&'short Path>;

你试图做的是从fs::remove_file 类型的强制:

∀ P: AsRef<Path>, P → io::Result<()>

到类型:

∀ 'r, &'r Path → io::Result<()>

函数指针类型在生命周期内仍然是通用的。我不认为这种强制无法完成是有原因的,但是Rust has some issues in this area

Rust 理解的最直接的解决方法是使用闭包:

let _ : fn(&Path) -> io::Result<()> = |p| fs::remove_file(p);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-09
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多