匹配内部可变枚举的预期方法是什么?
What is the intended way to match an interior mutable enum?
这些是我可以想出的方法来尝试匹配引用计数的内部可变枚举:
#![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()));
}
然而,大多数方法都会产生类型不匹配的错误,例如
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
}
这是预期的方式吗?即使是只读访问?
您可以使用 Ref
的 Deref
实现:
fn is_baz_get(foo_ref: Rc<RefCell<Foo>>) -> bool {
match *foo_ref.borrow() {
Foo::Bar(_) => false,
Foo::Baz(_) => true
}
}
这些是我可以想出的方法来尝试匹配引用计数的内部可变枚举:
#![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()));
}
然而,大多数方法都会产生类型不匹配的错误,例如
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
}
这是预期的方式吗?即使是只读访问?
您可以使用 Ref
的 Deref
实现:
fn is_baz_get(foo_ref: Rc<RefCell<Foo>>) -> bool {
match *foo_ref.borrow() {
Foo::Bar(_) => false,
Foo::Baz(_) => true
}
}