Rust中的多态性:规范方式

时间:2017-12-16 21:57:13

标签: rust polymorphism

在Rust中执行以下操作的规范方法是什么?

let s: Shape;
if something {
    s = Circle::new();
} else {
    s = Square::new();
}

对我来说最明显的方式是:

use std::env;

trait Shape {
    fn area(&self) -> f32;
}

struct Circle {
    rad: f32,
}

impl Circle {
    pub fn new() -> Circle {
        Circle {
            rad: 5.0,
        }
    }
}

impl Shape for Circle {
    fn area(&self) -> f32 {
        self.rad * self.rad * 3.14159
    }
}

struct Square {
    len: f32,
}

impl Square {
    pub fn new() -> Square {
        Square {
            len: 5.0,
        }
    }
}

impl Shape for Square {
    fn area(&self) -> f32 {
        self.len * self.len
    }
}

fn main() {
    let args: Vec<String> = env::args().collect();

    let s: Shape;
    if args.len() > 1 {
        s = Circle::new();
    } else {
        s = Square::new();
    }
    println!("Area: {}", s.area());
}

结果:

error[E0277]: the trait bound `Shape: std::marker::Sized` is not satisfied
 --> src/main.rs:46:9
   |
46 |     let s: Shape;
   |         ^ `Shape` does not have a constant size known at compile-time
   |

一般来说,Circle和Square可能确实有不同的尺寸,所以我们真的不能知道什么尺寸的&#39; s&#39;将在编译时。

这个问题Polymorphism in Rust似乎表明你需要编写一个包装器结构(在这个例子中称为ShapeStruct),它采用泛型,并且你可以在这里分解出trait实现的每个函数:

struct ShapeStruct<T> {
    shape: T,
}

impl<T: Shape> ShapeStruct<T> {
    fn area(&self) -> f32 {
        self.shape.area()
    }
}

但是这会产生很多样板 - 特征声明的每个功能都需要突破,例如&#39; area&#39;在上面突破了。有没有更好的办法?

0 个答案:

没有答案