兩個鐵銹打嗝-Fn尺寸未知,閉合為Fn一次

我想創建一個通用函數,它獲取目錄的路徑并在其上爬行,將可選函數應用于在該目錄和每個子目錄中找到的每個文件。

我在兩個我不明白的案子上遇到了死胡同。

這是第一例。我只對一個目錄應用函數,但不知道如何鍵入我的None案例:


fn main() {

    fn file_fn (file: &str) {
        println!("file: {:?}", file)
    }

    fn dir_fn (file: &str) {
        println!("dir:  {:?}", file)
    }

    // Passing case 
    apply_dir(".", Some(file_fn), Some(dir_fn));

    // Failing case
    apply_dir(".", Some(file_fn), None::<dyn Fn(&str)>);
                               // ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time

}


fn apply_dir<F, G> (dir: &str, file_func: Option<F>, dir_func: Option<G>)
where F: Fn(&str), G: Fn(&str) {
    for path in read_dir(dir).unwrap() {
        if path.is_dir() {
            match dir_func {
                Some(ref func) => func(path.to_str().unwrap()),
                _ => (),
            }
        } else {
            match file_func {
                Some(ref func) => func(path.to_str().unwrap()),
                _ => (),
            }
        }
    }
}


fn read_dir(dir: &str) -> io::Result<Vec<PathBuf>> {

    let mut paths = fs::read_dir(dir)?
        .map(|res| res.map(|e| e.path()))
        .collect::<Result<Vec<_>, io::Error>>()?;

    paths.sort();
    Ok(paths)
}

我在類型中有dyn,因為它無論如何都會自動執行,并且沒有聲明它有一天會被棄用,但我不知道它會做什么。

這是第二種情況。我正在嘗試對目錄進行爬網,并將該函數應用于子目錄中的每個文件。

fn main() {

    fn file_fn (file: &str) {
        println!("file: {:?}", file)
    }

    crawl_dir(".", Some(file_fn));
}


// --- same apply_dir and read_dir functions


fn crawl_dir<F> (dir: &str, file_func: Option<F>)
where F: Fn(&str) {
    apply_dir(dir, file_func, Some(|f| crawl_dir(f, file_func)));
 // ---------                      ^^^^^^^^^^^^^^^^^---------^
 // |                              |                |
 // |                              |                closure is `FnOnce` because it moves the variable `file_func` out of its environment
 // |                              this closure implements `FnOnce`, not `Fn`
 // the requirement to implement `Fn` derives from here
}

我基本上理解這個錯誤,但我不知道如何修復它。

file_func的所有權被閉包占有,它被閉包消耗,使它成為FnOnce。我找不到如何將閉包傳遞為Fn,即使我沒有從它的作用域之外向它傳遞任何參數。

? 最佳回答:

dyn描述的是某個類型具有某些功能,bit沒有說明該類型的數據,因此沒有說明任何大小。

dyn Fn(&str)表示可以使用&str參數調用傳入的類型,但這不足以確定需要為該類型分配多少內存。例如,兩者

let a = |file: &str| {
    println!("dir:  {:?}", file)
};

and

let prefix = "dir: ";
let b = |file: &str| {
    println!("{}{:?}", &prefix, file)
};

堅持dyn func(&str),但b占用更多空間,因為它還需要存儲對prefix的引用。

要解決第一個問題,可以傳入具有固定大小的類型,例如fn(&str)函數指針。

apply_dir(".", Some(file_fn), None::<fn(&str)>);

至于第二個問題,它說的是因為關閉是file_func的所有權

Some(|f| crawl_dir(f, file_func)))

在這個閉包被調用之后,file_func將不再能夠被使用,但是您需要多次調用這個閉包(每個文件一次),因此需要多次使用file_func。因此,file_func的所有權需要遠離關閉。

如果改為使用引用,則閉包將不具有所有權,并且可以多次調用它。

fn main() {
    crawl_dir(".", &Some(file_fn));
}

fn crawl_dir<F> (dir: &str, file_func: &Option<F>)
    where F: Fn(&str) {
    apply_dir(dir, file_func, Some(|f: &str| crawl_dir(f, file_func)));
}
fn apply_dir<F, G> (dir: &str, file_func: &Option<F>, dir_func: Option<G>)
where F: Fn(&str), G: Fn(&str) {
    ...
}
主站蜘蛛池模板: 日韩精品人妻av一区二区三区| 亚洲国产福利精品一区二区| 精品一区二区三区在线播放视频 | 一区二区三区四区在线播放| 亚洲国产美国国产综合一区二区| 一区二区三区免费在线视频| 韩国资源视频一区二区三区| 无码人妻精品一区二区三区99性| 国产一区二区三区在线看| 狠狠综合久久av一区二区 | 日本人真淫视频一区二区三区| 日本免费一区二区在线观看| 国产精品女同一区二区| 一区二区三区人妻无码| 国产精品自在拍一区二区不卡| 福利电影一区二区| 一区二区三区在线播放| 一区二区三区无码高清| 国产一区二区三区小向美奈子| 国内精品视频一区二区八戒| 韩国资源视频一区二区三区| 国模精品视频一区二区三区| 国产Av一区二区精品久久| 免费看无码自慰一区二区| 国内精品视频一区二区八戒| 视频一区二区三区免费观看| 精品人妻一区二区三区四区在线| 精品无码国产AV一区二区三区| 日韩精品一区在线| 精品在线一区二区三区| 久久一区二区三区99| 中文字幕人妻丝袜乱一区三区 | 久久精品动漫一区二区三区| 久久久久成人精品一区二区| 亚洲AV综合色一区二区三区| 久久久久人妻精品一区二区三区 | 国产一区二区三区国产精品| 无码精品人妻一区| 亚洲线精品一区二区三区| 激情内射亚洲一区二区三区| 四虎在线观看一区二区|