如何隐式绑定let/match操作的成员?以Rust叉积函数实现为例
Rust枚举匹配避免变量遮蔽的方法
针对你遇到的变量遮蔽问题,有几种更简洁的方式替代显式临时变量赋值:
方法一:解构时直接指定别名
在第一个if let解构时,直接将lhs的分量绑定到带前缀的别名上,避免后续被rhs的解构变量遮蔽:
pub fn cross(lhs: ThreeD, rhs: ThreeD) -> ThreeD { if let Vector { x: lhs_x, y: lhs_y, z: lhs_z } = lhs { if let Vector { x, y, z } = rhs { // 正确的叉积计算逻辑 Vector { x: lhs_y * z - lhs_z * y, y: lhs_z * x - lhs_x * z, z: lhs_x * y - lhs_y * x } } else { panic!("Cannot calculate cross product with a point") } } else { panic!("Cannot calculate cross product against a point") } }
方法二:使用match同时匹配两个参数
通过一次性匹配lhs和rhs的组合,直接解构出两组分量,代码结构更清晰,也从根源上避免了变量遮蔽:
pub fn cross(lhs: ThreeD, rhs: ThreeD) -> ThreeD { match (lhs, rhs) { (Vector { x: x1, y: y1, z: z1 }, Vector { x: x2, y: y2, z: z2 }) => { Vector { x: y1 * z2 - z1 * y2, y: z1 * x2 - x1 * z2, z: x1 * y2 - y1 * x2, } } (Point { .. }, _) => panic!("Cannot calculate cross product against a point"), (_, Point { .. }) => panic!("Cannot calculate cross product with a point"), } }
方法三:给枚举添加辅助方法提取分量
如果可以修改ThreeD枚举的定义,添加一个辅助方法来提取Vector的分量,能让cross函数的逻辑更简洁:
首先扩展枚举的实现:
enum ThreeD { Point { x: f64, y: f64, z: f64 }, Vector { x: f64, y: f64, z: f64 }, } impl ThreeD { fn into_vector(self) -> (f64, f64, f64) { match self { ThreeD::Vector { x, y, z } => (x, y, z), _ => panic!("Cannot calculate cross product with a point"), } } }
然后重写cross函数:
pub fn cross(lhs: ThreeD, rhs: ThreeD) -> ThreeD { let (x1, y1, z1) = lhs.into_vector(); let (x2, y2, z2) = rhs.into_vector(); Vector { x: y1 * z2 - z1 * y2, y: z1 * x2 - x1 * z2, z: x1 * y2 - y1 * x2, } }
内容的提问来源于stack exchange,提问作者Andy
相关产品推荐
相关产品推荐

