Rust学习教程26 - 特征对象

本文节选自<<Rust语言圣经>>一书
欢迎大家加入Rust编程学院,一起学习交流:
QQ群:1009730433

特征对象

在上一节中有一段代码无法通过编译:

fn returns_summarizable(switch: bool) -> impl Summary {
   
    if switch {
   
        Post {
   
           // ...
        }
    } else {
   
        Weibo {
   
            // ...
        }
    }
}

其中PostWeibo都实现了Summary特征,因此上面的函数试图通过返回impl Summary来返回这两个类型,但是编译器无情的报错了,原因是
impl Trait的返回值类型并不支持多种不同的类型返回,那如果我们想返回多种类型,该怎么办?

再来考虑一个问题: 现在在做一款游戏,需要将多个对象渲染在屏幕上,这些对象拥有不同的类型,存储在列表中,渲染的时候,循环该列表顺序渲染每个对象即可,在Rust中该怎么实现?

聪明的同学可能已经能想到一个办法,利用枚举:

#[derive(Debug)]
enum UiObject {
   
    Button,
    SelectBox,
}

fn main() {
   
    let objects = [
        UiObject::Button,
        UiObject::SelectBox
    ];

    for o in objects {
   
        draw(o)
    }
}

fn draw(o: UiObject) {
   
    println!("{:?}",o);
}

Bingo,这个确实是一个办法,但是问题来了,如果你的对象集合并不能明确知道呢?或者别人想要实现一个UI组件呢?是不是还要修改你的代码增加一个枚举成员?

总之,在编写这个UI库时,我们无法知道所有的UI对象类型,只知道的是:

  • UI对象的类型不同
  • 需要一个统一的类型来处理这些对象,无论是作为函数参数还是作为列表中的一员
  • 需要对每一个对象调用draw方法

在拥有继承的语言中,可以定义一个名为 Component 的类,该类上有一个 draw 方法。其他的类比如 ButtonImageSelectBox 会从 Component 派生并因此继承 draw 方法。它们各自都可以覆盖 draw 方法来定义自己的行为,但是框架会把所有这些类型当作是 Component 的实例,并在其上调用 draw。不过 Rust 并没有继承,我们得另寻出路。

特征对象定义

为了解决上面的所有问题,Rust引入了一个概念 - 特征对象。

在介绍特征对象之前,先来为之前的UI组件定义一个特征:

pub trait Draw {
   
    fn draw(&self);
}

只要组件实现了Draw特征,就可以调用draw方法来进行渲染。假设有一个ButtonSelectBox组件实现了Draw特征:

pub struct Button {
   
    pub width: u32,
    pub height: u32,
    pub label: String,
}

impl Draw for Button {
   
    fn 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值