我正在尝试
match
反对文件扩展名:
let file_path = std::path::Path::new("index.html");
let content_type = match file_path.extension() {
None => "",
Some(os_str) => match os_str {
"html" => "text/html",
"css" => "text/css",
"js" => "application/javascript",
},
};
编译器说:
error[E0308]: mismatched types
--> src/main.rs:6:13
|
6 | "html" => "text/html",
| ^^^^^^ expected struct `std::ffi::OsStr`, found str
|
= note: expected type `&std::ffi::OsStr`
found type `&'static str`
OsStr
和 OsString
的存在正是因为文件名不是 UTF-8。 Rust 字符串文字是 UTF-8。这意味着您必须处理两种表示形式之间的转换。
一种解决方案是放弃
match
并使用 if-else 语句。请参阅 Stargateur 的回答 作为示例。
您还可以将扩展名转换为字符串。由于扩展名可能不是 UTF-8,因此会返回另一个
Option
:
fn main() {
let file_path = std::path::Path::new("index.html");
let content_type = match file_path.extension() {
None => "",
Some(os_str) => match os_str.to_str() {
Some("html") => "text/html",
Some("css") => "text/css",
Some("js") => "application/javascript",
_ => panic!("You forgot to specify this case!"),
},
};
}
如果您希望所有情况都使用空字符串作为后备,您可以执行以下操作:
use std::ffi::OsStr;
fn main() {
let file_path = std::path::Path::new("index.html");
let content_type = match file_path.extension().and_then(OsStr::to_str) {
Some("html") => "text/html",
Some("css") => "text/css",
Some("js") => "application/javascript",
_ => "",
};
}
或者如果您想使用
None
作为后备:
use std::ffi::OsStr;
fn main() {
let file_path = std::path::Path::new("index.html");
let content_type = file_path.extension().and_then(OsStr::to_str).and_then(|ext| {
match ext {
"html" => Some("text/html"),
"css" => Some("text/css"),
"js" => Some("application/javascript"),
_ => None,
}
});
}
PartialEq<str>
特征来表示 OsStr
。
fn main() {
let file_path = std::path::Path::new("index.html");
let content_type = match file_path.extension() {
None => "",
Some(os_str) => {
if os_str == "html" {
"text/html"
} else if os_str == "css" {
"text/css"
} else if os_str == "js" {
"application/javascript"
} else {
""
}
}
};
println!("{:?}", content_type);
}