匹配内部可变枚举的预期方法是啥?

Posted

技术标签:

【中文标题】匹配内部可变枚举的预期方法是啥?【英文标题】:What is the intended way to match an interior mutable enum?匹配内部可变枚举的预期方法是什么? 【发布时间】:2019-06-26 22:50:28 【问题描述】:

这些是我可以想出的尝试匹配引用计数的内部可变枚举的方法:

#![allow(unused)]

use std::cell::RefCell;
use std::rc::Rc;

#[derive(Debug, Clone, PartialEq)]
struct Bar 
    some_bar: Vec<f64>,

#[derive(Debug, Clone, PartialEq)]
struct Baz 
    some_baz: i32,


#[derive(Debug, Clone, PartialEq)]
enum Foo 
    Bar(Bar),
    Baz(Baz),


fn is_baz(foo_ref: Rc<RefCell<Foo>>) -> bool 
    match foo_ref 
        Foo::Bar(_) => false,
        Foo::Baz(_) => true,
    


fn is_baz_borrow(foo_ref: Rc<RefCell<Foo>>) -> bool 
    match foo_ref.borrow() 
        Foo::Bar(_) => false,
        Foo::Baz(_) => true,
    


fn is_baz_deref(foo_ref: Rc<RefCell<Foo>>) -> bool 
    match *foo_ref 
        Foo::Bar(_) => false,
        Foo::Baz(_) => true,
    


fn is_baz_get_mut(foo_ref: Rc<RefCell<Foo>>) -> bool 
    match foo_ref.get_mut() 
        Foo::Bar(_) => false,
        Foo::Baz(_) => true,
    


fn is_baz_as_ref(foo_ref: Rc<RefCell<Foo>>) -> bool 
    match foo_ref.as_ref() 
        Foo::Bar(_) => false,
        Foo::Baz(_) => true,
    


fn is_baz_as_ref_borrow(foo_ref: Rc<RefCell<Foo>>) -> bool 
    match foo_ref.as_ref().borrow() 
        Foo::Bar(_) => false,
        Foo::Baz(_) => true,
    


fn is_baz_get_mut_mut(mut foo_ref: Rc<RefCell<Foo>>) -> bool 
    match foo_ref.get_mut() 
        Foo::Bar(_) => false,
        Foo::Baz(_) => true,
    


fn main() 
    let foo = Foo::Bar(Bar 
        some_bar: vec![1.1, 999.0],
    );
    let foo_ref = Rc::new(RefCell::new(foo));

    // none of these work
    assert!(is_baz(foo_ref.clone()));
    assert!(is_baz_borrow(foo_ref.clone()));
    assert!(is_baz_deref(foo_ref.clone()));
    assert!(is_baz_get_mut(foo_ref.clone()));
    assert!(is_baz_as_ref(foo_ref.clone()));
    assert!(is_baz_as_ref_borrow(foo_ref.clone()));

    // this works
    assert!(is_baz_get_mut_mut(foo_ref.clone()));

Playground

但是,大多数方式都会产生类型不匹配的错误,例如

error[E0308]: mismatched types
  --> src/main.rs:24:9
   |
24 |         Foo::Baz(_) => true
   |         ^^^^^^^^^^^ expected struct `std::rc::Rc`, found enum `Foo`
   |
   = note: expected type `std::rc::Rc<std::cell::RefCell<Foo>>`
              found type `Foo`

error[E0308]: mismatched types
  --> src/main.rs:30:9
   |
30 |         Foo::Bar(_) => false,
   |         ^^^^^^^^^^^ expected struct `std::cell::Ref`, found enum `Foo`
   |
   = note: expected type `std::cell::Ref<'_, Foo, >`
              found type `Foo`

唯一可行的方法是:

match foo_ref.get_mut() 
    Foo::Bar(_) => false,
    Foo::Baz(_) => true

这是预期的方式吗?即使是只读访问?

【问题讨论】:

【参考方案1】:

您可以使用RefDeref impl:

fn is_baz_get(foo_ref: Rc<RefCell<Foo>>) -> bool 
    match *foo_ref.borrow() 
        Foo::Bar(_) => false,
        Foo::Baz(_) => true
    

【讨论】:

非常感谢!这让我发疯了!如果我使用 ref rust fn is_baz_of_5_deref_borrow(foo_ref: Rc&lt;RefCell&lt;Foo&gt;&gt;) -&gt; bool match *foo_ref.borrow() Foo::Bar(_) =&gt; false, Foo::Baz(ref baz) =&gt; baz ==&amp;Bazsome_baz:5 ,我什至可以读取枚举的内容

以上是关于匹配内部可变枚举的预期方法是啥?的主要内容,如果未能解决你的问题,请参考以下文章

iOS 开发--NSMutableArray使用枚举方法

Objective C — 枚举数组最快和最有效的方法是啥?

在 Python 中设置枚举的最简洁方法是啥? [复制]

在 PHP 7 中创建类似枚举的行为的推荐方法是啥? [复制]

C#中的“对象被枚举”是啥意思?

枚举类+抽象方法+内部类