如何模式匹配包含 &mut 枚举的元组并在一个匹配臂中使用枚举并在另一个匹配臂中使用递归调用? [英] How can I pattern match a tuple containing a &mut enum and use the enum in one match arm and a recursive call in another?

查看:78
本文介绍了如何模式匹配包含 &mut 枚举的元组并在一个匹配臂中使用枚举并在另一个匹配臂中使用递归调用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码如何编译?看起来非常安全,但我无法说服编译器它是.

How can the code below be made to compile? It seems perfectly safe, but I can't convince the compiler that it is.

匹配*self的版本给出错误:

error[E0507]: cannot move out of borrowed content
 --> src/main.rs:8:16
  |
8 |         match (*self, y) {
  |                ^^^^^ cannot move out of borrowed content

self 匹配的版本给出:

The version matching self gives:

error[E0382]: use of moved value: `*self`
  --> src/main.rs:17:26
   |
8  |         match (self, y) {
   |                ---- value moved here
...
17 |                 (*a * b, self)
   |                          ^^^^ value used here after move
   |
   = note: move occurs because `self` has type `&'a mut Foo<'a>`, which does not implement the `Copy` trait

enum Foo<'a> {
    Foo1(Option<&'a mut Foo<'a>>),
    Foo2(i16),
}

impl<'a> Foo<'a> {
    fn bar(&'a mut self, y: i16) -> (i16, &'a mut Foo<'a>) {
        match (self, y) {
            (&mut Foo::Foo1(Some(ref mut a)), b) if (b == 5) => {
                return a.bar(y)
            },

            (&mut Foo::Foo2(ref mut a), b) if (b == 5) => {
                print!("is five");
                *a = (b + 42) as i16;

                (*a * b, self)
            },

            ref mut x => {
                print!("is not five!");
                (y, self)
            }
        }
    }
}

我觉得我需要一个像下面这样的匹配臂,但它似乎不是有效的语法:

I feel like I would need a match arm such as the following, but it doesn't seem to be valid syntax:

(ref mut f @ Foo::Foo1, b) if (b == 5) => {
    print!("is five");
    f.0 = b + 42;
    (b, f)
} 

error[E0532]: expected unit struct/variant or constant, found tuple variant `Foo::Foo1`
  --> src/main.rs:24:30
   |
24 |                 (ref mut f @ Foo::Foo1, b) if (b == 5) => {
   |                              ^^^^^^^^^ not a unit struct/variant or constant

这是我正在尝试编写的 toml::Valuedeep_fetch_mut 的简化版本.目标是能够调用 .deep_fetch_mut(vec!["aaa","bbb","ccc"]),这将在 中返回对该值的可变引用toml::Value.

This is a dumbed down version of a deep_fetch_mut of a toml::Value that I am trying to write. The goal would be to be able to call .deep_fetch_mut(vec!["aaa","bbb","ccc"]), that will return a mutable reference to that value inside the toml::Value.

这个问题是如何模式匹配包含 &mut 枚举的元组并在匹配臂中使用该枚举?

推荐答案

这个貌似可以编译,但是非常难看.有没有办法简化这个?

This seems to compile, but it's very ugly. Is there a way to simplify this?

enum Foo<'a> {
    Foo1(Option<&'a mut Foo<'a>>),
    Foo2(i16),
}

impl<'a> Foo<'a> {
    fn bar(&'a mut self, y: i16) -> (i16, &'a mut Foo<'a>) {
        match (&mut *self, y) {
            (Foo::Foo1(Some(ref mut a)), b) if (b == 5) => {
                return a.bar(y)
            },

            (self2, c) => {
                let n = match (&mut *self2 , c) {
                    (Foo::Foo2(ref mut a), b) if (b == 5) => {
                        print!("is five");
                        *a = (b + 42) as i16;

                        *a * b
                    },

                    ref mut x => {
                        print!("is not five!");
                        y
                    }
                };

                return (n, self2)
            }
        }
    }
}

这篇关于如何模式匹配包含 &amp;mut 枚举的元组并在一个匹配臂中使用枚举并在另一个匹配臂中使用递归调用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆