簡體   English   中英

用於從Rust中的給定路徑中提取文件擴展名

[英]Extracting a file extension from a given path in Rust idiomatically

我試圖從給定的String路徑中提取文件的擴展名。

下面這段代碼可以工作,但我想知道是否有一個更干凈,更慣用的Rust方法來實現這個目的:

use std::path::Path;

fn main() {

    fn get_extension_from_filename(filename: String) -> String {

        //Change it to a canonical file path.
        let path = Path::new(&filename).canonicalize().expect(
            "Expecting an existing filename",
        );

        let filepath = path.to_str();
        let name = filepath.unwrap().split('/');
        let names: Vec<&str> = name.collect();
        let extension = names.last().expect("File extension can not be read.");
        let extens: Vec<&str> = extension.split(".").collect();

        extens[1..(extens.len())].join(".").to_string()
    }

    assert_eq!(get_extension_from_filename("abc.tar.gz".to_string()) ,"tar.gz" );
    assert_eq!(get_extension_from_filename("abc..gz".to_string()) ,".gz" );
    assert_eq!(get_extension_from_filename("abc.gz".to_string()) , "gz");

}

在慣用Rust中,可能失敗的函數的返回類型應該是OptionResult 通常,函數也應該接受切片而不是String並且只在必要時創建一個新的String 這減少了過多的復制和堆分配。

您可以使用提供的extension()方法,然后將生成的OsStr轉換為&str

use std::path::Path;
use std::ffi::OsStr;

fn get_extension_from_filename(filename: &str) -> Option<&str> {
    Path::new(filename)
        .extension()
        .and_then(OsStr::to_str)
}

assert_eq!(get_extension_from_filename("abc.gz"), Some("gz"));

使用and_then在這里很方便,因為這意味着你不必打開extension()返回的Option<&OsStr>並在調用to_str之前處理它是None的可能性。 我也可以使用lambda |s| s.to_str() |s| s.to_str()而不是OsStr::to_str - 它可能是一個偏好或意見的問題,哪個更慣用。

請注意,參數&str和返回值都是對為斷言創建的原始字符串切片的引用。 返回的切片不能超過它引用的原始切片,因此如果需要更長的時間,可能需要從此結果創建一個擁有的String

什么比使用Rust的內置方法更慣用?

Path::new(&filename).extension()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM