Как преобразовать функцию generi c в указатель функции со ссылочным параметром? - PullRequest
2 голосов
/ 03 августа 2020
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<'r> времени жизни более высокого порядка, но я не знаю, как ее решить.

Как мне это сделать с помощью объекта-признака? Следующее также не компилируется:

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

Я знаю, что могу создать функцию-оболочку вокруг fs::remove_file, но я бы хотел избежать этого и получить fs::remove_file, чтобы он стал указателем на функцию или чертой сам объект.

Это не дубликат этого Указатели функций в Rust с использованием ограниченных универсальных типов , так как я хотел бы получить указатель функции на конкретный экземпляр std::fs::remove_file с &Path в качестве параметра типа, но не иметь общего типа указателя на функцию c.

Я пробовал следующее, но это тоже не работает:

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

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

1 Ответ

0 голосов
/ 04 августа 2020

Я хотел бы получить указатель функции на конкретный экземпляр std::fs::remove_file с &Path в качестве параметра типа, но не иметь общий c тип указателя на функцию.

Это суть проблемы. Будет компилироваться конкретный экземпляр. Например:

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<()>

Тип указателя функции по-прежнему составляет c в течение всего времени жизни. Я не думаю, что есть причина, по которой такое принуждение не может быть выполнено, но Rust имеет некоторые проблемы в этой области .

Самый простой обходной путь, который понимает Rust, - это использовать закрытие:

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