Как обрабатывать сопоставление с образцом для нового типа перечисления, завернутого в R c >? - PullRequest
0 голосов
/ 08 февраля 2020

Фон

Я пишу библиотеку, ниже показан некоторый связанный код:

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<RefCell<MyEnum>> , Поэтому я хочу спрятать его в структуре нового типа, как описано в псевдонимы типа «возможно, для реализации, для методов по типу» :

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

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

И я не Я не хочу, чтобы другие, кто использует мой ящик, знали о существовании Rc<RefCell<>>.

Проблема

Если я использую ExposedMyEnum, чтобы скрыть надоедливые Rc<RefCell<MyEnum>>, я не могу выполнить сопоставление с образцом как 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 */ }
    }
}

Мне нужно создать структуры нового типа для каждого варианта, который не изящный.

1 Ответ

1 голос
/ 08 февраля 2020

Решение довольно простое: можно обращаться к членам кортежа и структуры, подобной кортежу, по синтаксису .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 */ }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...