假设我有一个具有两个变量的枚举,每个变量都包含不同类型的单个值--并且枚举在这两种类型上是泛型的:
enum AorB<A, B> {
A(A),
B(B),
}
在我的代码库中经常会发生这样的事情,即我知道我收到的是哪个变量,并且我需要解开已知类型的内部值.我知道这可能会引起一些关于设计的问题,但让我们把这些放在一边.在任何情况下,我都想编写方便的展开方法,以避免每次出现这种情况时都要match
次.
这种情况基本上有两种形式:我有一个指向AorB<A, B>
的指针,我想得到一个指向内部值的指针;或者当我很乐意消费整个AorB<A, B>
对象时,我想得到内部值的所有权.这就产生了四种方法:
impl<A, B> AorB<A, B> {
fn unwrap_a(self) -> A {
match self {
AorB::A(a) => a,
_ => panic!(),
}
}
fn unwrap_b(self) -> B {
match self {
AorB::B(b) => b,
_ => panic!(),
}
}
fn unwrap_a_ref(&self) -> &A {
match self {
AorB::A(a) => a,
_ => panic!(),
}
}
fn unwrap_b_ref(&self) -> &B {
match self {
AorB::B(b) => b,
_ => panic!(),
}
}
}
My question is:有没有办法将这四个方法简化为两个(每个变体一个),并自动优雅地处理所拥有的 case 与参考 case ?
以下是我目前的 idea :
-
我知道有一些特性,比如
AsRef
和Borrow
,可以灵活地处理各种所有权情况,但我看不出如何将它们直接应用于上述方法. -
一种或多或少显而易见的解决方案是只保留
_ref
个方法,只要需要所有权就让调用者clone()
输出.我认为如果将e.unwrap_a()
替换为e.unwrap_a_ref().clone()
,e
将在调用后由borrow 判断器自动释放,因为它不会在以后使用(否则e.unwrap_a()
将不会编译),因此切换到_ref
方法基本上不会重复使用内存.这样对吗?在任何情况下,对clone()
的调用在调用者端都有一点不方便,而且它确实涉及到以unwrap_a
不需要的方式复制数据. -
第三种 Select 是只保留
_ref
个方法,并在AorB
定义中添加A: Deref
和B: Deref
.这与2非常相似,只是呼叫者不用拨打clone()
(据我所知).这种方法的一个小问题是,A
和B
在实践中将是我自己的类型,如果可能的话,我宁愿避免为它们实现Deref
,因为这可能是一个微妙的特征.
有没有比上面的2或3更好的方法来实现我所寻求的方法简化?