gpt4 book ai didi

rust - 如何在不重复方法的情况下为结构实现多个特征?

转载 作者:行者123 更新时间:2023-11-29 08:02:36 24 4
gpt4 key购买 nike

下面的代码工作得很好,但我重复了很多次而且我认为这不是真正的 Rustic。例如,我正在为 Square 实现两个特征,这感觉不对!此外,函数 coordinate() 在特征和实现中重复出现。

有没有一种方法可以实现这段代码而不用经常重复我自己?是否可以实现以下两个特征:

impl BasicInfo && Sides for Square {
....
}

上面的代码是行不通的,只是一个idea。当一个函数可以应用于多个结构时,是否可以在特征 BasicInfo 中只定义一次并访问它。

fn main() {
let x_1: f64 = 2.5;
let y_1: f64 = 5.2;
let radius_1: f64 = 5.5;
let width_01 = 10.54;

let circle_01 = Circle { x: x_1, y: y_1, radius: radius_1 };
let square_01 = Square { x: x_1, y: y_1, width: width_01, sides: 4 };

println!("circle_01 has an area of {:.3}.",
circle_01.area().round());
println!("{:?}", circle_01);
println!("The coordinate of circle_01 is {:?}.\n", circle_01.coordinate());
println!("coordinate of square_01: {:?} has an area of: {} m2 and also has {} sides.",
square_01.coordinate(),
(square_01.area() * 100.0).round() / 100.0,
square_01.has_sides() );
}

#[derive(Debug)]
struct Circle {
x: f64,
y: f64,
radius: f64,
}

struct Square {
x: f64,
y: f64,
width: f64,
sides: i32,
}

trait BasicInfo {
fn area(&self) -> f64;
// coordinate() is declared here, but not defined. Is it possible to define it here and still be able to access it when I want it.
fn coordinate(&self) -> (f64, f64);
}

trait Sides {
fn has_sides(&self) -> i32;
}

impl BasicInfo for Circle {
fn area(&self) -> f64 {
std::f64::consts::PI * (self.radius * self.radius)
}
// coordinate() gets defined again, and looks like repeating code
fn coordinate(&self) -> (f64, f64) {
(self.x, self.y)
}
}

impl BasicInfo for Square {
fn area(&self) -> f64 {
self.width.powf(2.0)
}
// coordinate() gets defined again, and looks like repeating code
fn coordinate(&self) -> (f64, f64) {
(self.x, self.y)
}
}

impl Sides for Square {
fn has_sides(&self) -> i32 {
self.sides
}
}

最佳答案

对于你的第二个问题(避免重复 coordinate 的相同实现)我想向你展示基于宏的解决方案。

有趣的是,它给你留下了 3 个特征而不是 2 个,所以它与你的第一个问题完全相反。我想你不能拥有一切! :)

// factoring out the Coordinates trait from BasicInfo
trait Coordinates {
fn coordinate(&self) -> (f64, f64);
}

// but we can require implementors of BasicInfo to also impl Coordinates
trait BasicInfo: Coordinates {
fn area(&self) -> f64;
}

// helper macro to avoid repetition of "basic" impl Coordinates
macro_rules! impl_Coordinates {
($T:ident) => {
impl Coordinates for $T {
fn coordinate(&self) -> (f64, f64) { (self.x, self.y) }
}
}
}

#[derive(Debug)]
struct Circle {
x: f64,
y: f64,
radius: f64,
}

#[derive(Debug)]
struct Square {
x: f64,
y: f64,
width: f64,
sides: i32,
}

// the macro here will expand to identical implementations
// for Circle and Square. There are also more clever (but a bit
// harder to understand) ways to write the macro, so you can
// just do impl_Coordinates!(Circle, Square, Triangle, OtherShape)
// instead of repeating impl_Coordinates!
impl_Coordinates!(Circle);
impl_Coordinates!(Square);


trait Sides {
fn has_sides(&self) -> i32;
}

impl BasicInfo for Circle {
fn area(&self) -> f64 {
std::f64::consts::PI * (self.radius * self.radius)
}
}

impl BasicInfo for Square {
fn area(&self) -> f64 {
self.width.powf(2.0)
}
}

impl Sides for Square {
fn has_sides(&self) -> i32 {
self.sides
}
}

关于rust - 如何在不重复方法的情况下为结构实现多个特征?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34270031/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com