【问题标题】:How to handle pattern match for newtype of enum wrapped in Rc<RefCell<>>?如何处理包装在 Rc<RefCell<>> 中的新类型枚举的模式匹配?
【发布时间】:2020-02-08 08:33:24
【问题描述】:

背景

我正在写一个库,一些相关代码如下所示:

pub struct MyStruct1;

pub struct MyStruct2;

pub enum MyEnum {
    Variant1(MyStruct1),
    Variant2(MyStruct2)
}

// out of this crate
fn foo(my_enum: Rc<RefCell<MyEnum>>) {
    match &*my_enum.borrow() {
        Variant1(my_struct1) => { /* do something */ },
        Variant2(my_struct2) => { /* do something */ }
    }
}

目标

MyEnum 始终使用包裹在Rc&lt;RefCell&lt;MyEnum&gt;&gt; 中。所以我想将它隐藏在is-it-possible-to-implement-methods-on-type-aliases 中描述的新类型结构中:

//make this only public to crate
pub(crate) enum MyEnum;

pub struct ExposedMyEnum(pub(crate) Rc<RefCell<MyEnum>>);

而且我不希望其他使用我的 crate 的人知道Rc&lt;RefCell&lt;&gt;&gt; 的存在。

问题

如果我使用ExposedMyEnum 来隐藏烦人的Rc&lt;RefCell&lt;MyEnum&gt;&gt;,我就不能像foo 那样做模式匹配。

不优雅的解决方案

将原代码改为

struct MyStruct1;
struct MyStruct2;

pub struct ExposedMyStruct1(pub(crate) Rc<RefCell<MyStruct1>>);
pub struct ExposedMyStruct2(pub(crate) Rc<RefCell<MyStruct2>>);

pub enum MyEnum {
    Variant1(ExposedMyStruct1),
    Variant2(ExposedMyStruct1)
}

// out of this crate
fn foo(my_enum: &MyEnum) {
    match &my_enum {
        Variant1(my_struct1) => { /* do something */ },
        Variant2(my_struct2) => { /* do something */ }
    }
}

我需要为每个变体创建新类型结构,这并不优雅。

【问题讨论】:

    标签: rust


    【解决方案1】:

    解决方法比较简单:可以通过.0.1等语法来引用元组和类元组结构的成员,如下所示:

    use std::cell::RefCell;
    use std::rc::Rc;
    
    pub struct MyStruct1;
    
    pub struct MyStruct2;
    
    pub(crate) enum MyEnum {
        Variant1(MyStruct1),
        Variant2(MyStruct2),
    }
    
    pub struct ExposedMyEnum(pub(crate) Rc<RefCell<MyEnum>>);
    
    fn foo(my_enum: ExposedMyEnum) {
        match &*my_enum.0.borrow() {
            MyEnum::Variant1(my_struct1) => { /* do something */ }
            MyEnum::Variant2(my_struct2) => { /* do something */ }
        }
    }
    

    【讨论】:

    • 这行得通,但我不希望其他使用我的 crate 的人知道Rc&lt;RefCell&lt;&gt;&gt; 的存在,foo 是用户使用的示例方法。在您的实现中,使用borrow 仍然会泄漏RefCell 的东西,有什么方法可以实现我的目标吗?
    猜你喜欢
    • 1970-01-01
    • 2020-01-15
    • 2022-12-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多