根据枚举是什么变体,如何在其中返回两种不同的可能类型之一



类似的问题以前被问过很多次,但我最接近我的案例是这里。

我正在努力实现这样的目标(尽管比赛部分完全错误(。

struct A {
a: i8,
b: u8,
}
struct B {
c: i16,
d: u16,
}
enum select {
type_a(A),
type_b(B),
}
impl select {
fn return_one<T>(&self) -> T {
match self {
type_a(a) => a,
type_b(b) => b,
}
}
}

正如您所看到的,它有一个额外的警告,其中枚举中的值可以是两个结构中的任何一个。有没有一些仿制药的魔力我忽略了?也许我应该将类型与std::mem::discriminant()进行比较?我非常希望避免使用Option<T>的两种方法。

我能够制作出符合你要求的东西,但我不推荐它。

pub struct A {
a: i8,
b: u8,
}
pub struct B {
c: i16,
d: u16,
}
enum Select {
TypeA(A),
TypeB(B),
}
trait FromSelect {
fn from_select(sel: Select) -> Self;
}
impl FromSelect for A {
fn from_select(select: Select) -> Self {
match select {
Select::TypeA(a) => a,
_ => panic!("Tried to select B from A")
}
}
}
impl FromSelect for B {
fn from_select(select: Select) -> Self {
match select {
Select::TypeB(b) => b,
_ => panic!("Tried to select A from B")
}
}
}
impl Select {
fn return_one<T: FromSelect>(self) -> T {
FromSelect::from_select(self)
}
}
fn main() {
let s: Select = Select::TypeA(A { a: 5, b: 5 });
let _aa = s.return_one::<A>();
let s2: Select = Select::TypeA(A { a: 7, b: 7 });
// This Panics
let _bb = s2.return_one::<B>();
}

游乐场

我之所以说"Kind Of",是因为我无法定义不使用Select枚举的FromSelect特性,原因我不完全理解。

此外,你说你不想要两种不同的方法——我只是部分做到了。在这个解决方案中,定义了两个方法,但调用者不需要知道,因为它们是通过使用泛型抽象的。

正如你从主函数中看到的那样,你需要使用"turbofish"语法在编译时指定你想要返回的变量(或者你可以注释你要放入的变量(,但如果你弄错了,程序就会恐慌。更糟糕的是,编译器将无法警告您错误!

对我来说,这否定了你可能得到的任何微小好处。除此之外,还需要相当多的锅炉板。

最新更新