首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >复数在锈蚀中的实现

复数在锈蚀中的实现
EN

Code Review用户
提问于 2023-05-09 12:01:14
回答 1查看 83关注 0票数 1

我正在学习面向对象的编程在锈蚀。我为复数创建了自己的结构。请你回顾并回答我的问题:

  1. 是否可以实现类似C++的默认构造函数?我想用let c0 = my_math::Complex::default();代替let c0: Complex;
  2. 为什么我要实现PartialEq而不是Eq
  3. 我为什么要实现type Output = Complex;?我已经有-> Complex了。
代码语言:javascript
复制
     mod my_math {
        use std::fmt;
        use std::ops;
        use std::cmp::PartialEq;
    
        pub struct Complex {
            // Complex numbers (real, image * i)
            pub real: i32,
            pub imaginary: i32 
        }
    
        impl Complex {
            pub fn new(real: i32, imaginary: i32) -> Complex {
                Complex {real: real, imaginary: imaginary}
            }
        }
    
        impl Default for Complex {
            fn default() -> Self {
                Complex { real: 0, imaginary: 0}
            }
        }
    
        impl fmt::Display for Complex {
            fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
                write!(f, "({}, {}i)", self.real, self.imaginary)
            }
        }
    
        impl ops::Add for Complex {
            type Output = Complex;
            fn add(self, rhs: Complex) -> Complex {
                Complex {real: rhs.real + self.real, imaginary: rhs.imaginary + self.imaginary}
            }
        }
    
        impl ops::Sub for Complex {
            type Output = Complex;
            fn sub(self, rhs: Complex) -> Complex {
                Complex {real: self.real - rhs.real, imaginary: self.imaginary - rhs.imaginary}
            }
        }
    
        impl ops::Mul for Complex {
            type Output = Complex;
            fn mul(self, rhs: Complex) -> Self::Output {
                Complex {
                    real: self.real * rhs.real - self.imaginary * rhs.imaginary, 
                    imaginary: self.real * rhs.imaginary + self.imaginary * rhs.real
                }
            }
        }
    
        impl PartialEq for Complex {
            fn eq(&self, other: &Self) -> bool {
                self.real == other.real && self.imaginary == other.imaginary
            }
        }
    
        
    }
    
    
    fn main() {
        let c0 = my_math::Complex::default();
        assert!(c0.real == 0);
        assert!(c0.imaginary == 0);
    
        let c1 = my_math::Complex{real: 1, imaginary: 10};
        let c2 = my_math::Complex::new(2, 20);
        
        let c3 = c1 + c2;
        let c3_expected = my_math::Complex::new(3, 30);
        assert!(c3 == c3_expected);
        
        println!("{}", c3);
    }    
EN

回答 1

Code Review用户

回答已采纳

发布于 2023-05-09 13:59:29

派生PartialEq (可能还有Eq )和Default,而不是手动实现

代码语言:javascript
复制
#[derive(PartialEq, Default)]
pub struct Complex {
     // Complex numbers (real, image * i)
     pub real: i32,
     pub imaginary: i32 
}

这简化了代码。

删除use std::cmp::PartialEq;

这是多余的- PartialEq在前奏曲里

总是为您的类型#[derive(Debug)]提供

这允许以程序员-convienent格式打印它们。

Complex

实现CloneCopy

代码语言:javascript
复制
#[derive(Clone, Copy)]
pub struct Complex {
     // Complex numbers (real, image * i)
     pub real: i32,
     pub imaginary: i32 
}

这允许在需要时复制Complex,另外,实现Copy允许使用标准库类型进行一些优化。

在适当的时候使用assert_eq!()assert!(x == y)替换为assert_eq!(x, y)。这将打印xy,以防断言失败。这要求他们实现Debug

也实现Eq

我不知道你为什么决定不去实现它;你应该尽可能地去实现它。

用rustfmt

格式化代码

这使得您的代码遵循正式的锈蚀风格。

使用derive_more

这是不必要的(例如,我不会这样做),但是如果您可以引入依赖项,您可以避免手动实现操作系统,甚至可以避免使用new实现derive_more

代码语言:javascript
复制
#[derive(
    Debug,
    Clone,
    Copy,
    PartialEq,
    Eq,
    Default,
    derive_more::Constructor,
    derive_more::Add,
    derive_more::Sub,
)]
pub struct Complex {
    // Complex numbers (real, image * i)
    pub real: i32,
    pub imaginary: i32,
}

Complex中的注释更改为文档注释

这将更好地记录结构。

代码语言:javascript
复制
/// Complex numbers (real, image * i)
pub struct Complex {
    pub real: i32,
    pub imaginary: i32,
}

使用结构字段中的速记

如果您不将derive_more用于new(),而不是指定field: field,只需指定field

代码语言:javascript
复制
pub fn new(real: i32, imaginary: i32) -> Complex {
    Complex { real, imaginary }
}

不指定RHS的

类型

它默认为与实现类型相同的类型,因此不需要指定它。

代码语言:javascript
复制
impl ops::Mul for Complex { ... }

最终代码

包含derive_more在内的所有更改的代码:

代码语言:javascript
复制
mod my_math {
    use std::fmt;

    #[derive(
        Debug,
        Clone,
        Copy,
        PartialEq,
        Eq,
        Default,
        derive_more::Constructor,
        derive_more::Add,
        derive_more::Sub,
    )]
    /// Complex numbers (real, image * i)
    pub struct Complex {
        pub real: i32,
        pub imaginary: i32,
    }

    impl fmt::Display for Complex {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            write!(f, "({}, {}i)", self.real, self.imaginary)
        }
    }

    impl ops::Mul for Complex {
        type Output = Complex;
        fn mul(self, rhs: Complex) -> Self::Output {
            Complex {
                real: self.real * rhs.real - self.imaginary * rhs.imaginary,
                imaginary: self.real * rhs.imaginary + self.imaginary * rhs.real,
            }
        }
    }
}

fn main() {
    let c0 = my_math::Complex::default();
    assert_eq!(c0.real, 0);
    assert_eq!(c0.imaginary, 0);

    let c1 = my_math::Complex {
        real: 1,
        imaginary: 10,
    };
    let c2 = my_math::Complex::new(2, 20);

    let c3 = c1 + c2;
    let c3_expected = my_math::Complex::new(3, 30);
    assert_eq!(c3, c3_expected);

    println!("{}", c3);
}

不包括derive_more的所有更改的代码:

代码语言:javascript
复制
mod my_math {
    use std::fmt;
    use std::ops;

    #[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
    /// Complex numbers (real, image * i)
    pub struct Complex {
        pub real: i32,
        pub imaginary: i32,
    }

    impl Complex {
        pub fn new(real: i32, imaginary: i32) -> Complex {
            Complex { real, imaginary }
        }
    }

    impl fmt::Display for Complex {
        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
            write!(f, "({}, {}i)", self.real, self.imaginary)
        }
    }

    impl ops::Add for Complex {
        type Output = Complex;
        fn add(self, rhs: Complex) -> Complex {
            Complex {
                real: rhs.real + self.real,
                imaginary: rhs.imaginary + self.imaginary,
            }
        }
    }

    impl ops::Sub for Complex {
        type Output = Complex;
        fn sub(self, rhs: Complex) -> Complex {
            Complex {
                real: self.real - rhs.real,
                imaginary: self.imaginary - rhs.imaginary,
            }
        }
    }

    impl ops::Mul for Complex {
        type Output = Complex;
        fn mul(self, rhs: Complex) -> Self::Output {
            Complex {
                real: self.real * rhs.real - self.imaginary * rhs.imaginary,
                imaginary: self.real * rhs.imaginary + self.imaginary * rhs.real,
            }
        }
    }
}

fn main() {
    let c0 = my_math::Complex::default();
    assert_eq!(c0.real, 0);
    assert_eq!(c0.imaginary, 0);

    let c1 = my_math::Complex {
        real: 1,
        imaginary: 10,
    };
    let c2 = my_math::Complex::new(2, 20);

    let c3 = c1 + c2;
    let c3_expected = my_math::Complex::new(3, 30);
    assert_eq!(c3, c3_expected);

    println!("{}", c3);
}
```#qcStackCode#
代码语言:javascript
复制
票数 5
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/284886

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档