Rust 结构内部的模式匹配

Rust 结构内部的模式匹配,rust,Rust,我想使用模式匹配来检查结构的内部,而不构建新的结构。我试图交换结构的值作为练习(我知道mem::swap存在) 交换意味着匹配结构的一个值,然后交换匹配的值。像letx={10,20,30};x、 掉期(10,30)应产生{30,20,10} 我想做但做不到的事 #[derive(Debug, Clone, Copy)] struct Color { r: u8, g: u8, b: u8, a: u8, } impl Color { fn swap(m

我想使用模式匹配来检查结构的内部,而不构建新的结构。我试图交换结构的值作为练习(我知道
mem::swap
存在)

交换意味着匹配结构的一个值,然后交换匹配的值。像let
x={10,20,30};x、 掉期(10,30)
应产生
{30,20,10}

我想做但做不到的事

#[derive(Debug, Clone, Copy)]
struct Color {
    r: u8,
    g: u8,
    b: u8,
    a: u8,
}

impl Color {
    fn swap(mut self, first: u8, second: u8) -> Color {
        match (first) {
            self.r => {
                match (second) {
                    self.b => {
                        self.r = second;
                        self.b = first;
                    },
                    self.g => {
                        self.r = second;
                        self.g = first;
                    },
                    self.a => {
                        self.r = second;
                        self.a = first;
                    },
                    _ => {},
                }
            },
            _ => {}
        }

        Color {
            r: self.r,
            g: self.g,
            b: self.b,
            a: self.a,
        }
    }
}
fn main() {
    let c = Color {
        r: 255,
        g: 200,
        b: 10,
        a: 30,
    };

    let color = c.swap(c.r, c.a);

    println!("{:?}", color);
}

代码无效,这是我想要完成的。有办法做到这一点吗?我想我已经偏离了这种方法的基础

从技术上讲,有一种方法可以通过模式匹配来实现这一点,但在实践中您可能永远不会看到这一点。缺少的部分是使用:

但这并没有真正使用模式匹配的任何有用部分;这只是一堆if-else子句:

if first == self.r {
    if second == self.b {
        self.r = second;
        self.b = first;
    } else if second == self.g {
        self.r = second;
        self.g = first;
    } else if second == self.a {
        self.r = second;
        self.a = first;
    }
}
不过,您可以选择在某些模式下使用鞋钉:

let x1 = (first == self.r, first == self.g, first == self.b, first == self.a);
let x2 = (second == self.r, second == self.g, second == self.b, second == self.a);

match (x1, x2) {
    ((true, _, _, _), (_, true, _, _)) => {
        self.r = second;
        self.b = first;
        }
    ((true, _, _, _), (_, _, true, _)) => {
        self.r = second;
        self.g = first;
        }
    ((true, _, _, _), (_, _, _, true)) => {
        self.r = second;
        self.a = first;
    }
    _ => {}
}

{10,20,10,20}.swap(10,20)
产生了什么?交换(10,20)这是一个关于匹配内部结构的练习,这是我真正关心的,但会一直切换所有匹配项。你是否已经意识到
匹配
只需要一只手臂?我没有,但这很理想。无可否认,我是一个完全的新手。事实上,这是唯一有意义的事情,或者=>总是会评估。太棒了。我知道我的方法不是这样做的,但我很好奇你是否能做到。我一直认为匹配是一种切换情况,但我想这有点不同。@MitchellIngram认为它是一种C
切换
的一次近似。然而,C的
开关
不允许带有动态值的
大小写
,所以也许我误解了你?就像这样:@MitchellIngram ah,一个JS
开关
;是的,锈迹与此相当不同,因为匹配的图案必须进行静态检查。这是有道理的,只是需要一点时间来适应。学习总是很兴奋。谢谢你的帮助!
let x1 = (first == self.r, first == self.g, first == self.b, first == self.a);
let x2 = (second == self.r, second == self.g, second == self.b, second == self.a);

match (x1, x2) {
    ((true, _, _, _), (_, true, _, _)) => {
        self.r = second;
        self.b = first;
        }
    ((true, _, _, _), (_, _, true, _)) => {
        self.r = second;
        self.g = first;
        }
    ((true, _, _, _), (_, _, _, true)) => {
        self.r = second;
        self.a = first;
    }
    _ => {}
}