这是一个简化的测试用例:
use std::path::PathBuf;
fn main() {
let paths: Vec<PathBuf> = Vec::new();
let defaults: Vec<&'static str> = Vec::new();
let result = match 1 {
1 => paths,
_ => defaults,
};
}
正如错误消息试图说明的那样,Rust 要求单个变量始终具有相同的类型。让一个变量成为一组中的未知类型根本没有意义。
您可以做的最直接的事情就是创建一个enum
这包含了您拥有的两种情况:
use std::path::PathBuf;
enum MyThing<'a> {
Str(&'a str),
Path(PathBuf),
}
fn main() {
let paths: Vec<PathBuf> = Vec::new();
let defaults: Vec<&'static str> = Vec::new();
let result: Vec<_> = match 1 {
1 => paths.into_iter().map(MyThing::Path).collect(),
_ => defaults.into_iter().map(MyThing::Str).collect(),
};
}
您也可以选择一个中间立场并转换为该类型,也许String
:
use std::path::PathBuf;
fn main() {
let paths: Vec<PathBuf> = Vec::new();
let defaults: Vec<&'static str> = Vec::new();
let result: Vec<_> = match 1 {
1 => paths.into_iter().map(|p| p.to_string_lossy().into_owned()).collect(),
_ => defaults.into_iter().map(|s| s.to_string()).collect(),
};
}
第三个选项是创建一个trait并为这两种类型实现它。然后您可以创建一个特质对象。此选项最接近您可能熟悉的动态语言。它添加了额外的间接层,从而提供了更大的灵活性:
use std::path::PathBuf;
trait MyTrait {
fn size(&self) -> u8;
}
impl MyTrait for PathBuf {
fn size(&self) -> u8 {
15
}
}
impl<'a> MyTrait for &'a str {
fn size(&self) -> u8 {
88
}
}
fn main() {
let paths: Vec<PathBuf> = Vec::new();
let defaults: Vec<&'static str> = Vec::new();
let result: Vec<_> = match 1 {
1 => paths.into_iter().map(|p| Box::new(p) as Box<MyTrait>).collect(),
_ => defaults.into_iter().map(|s| Box::new(s) as Box<MyTrait>).collect(),
};
}