学习新时代编程语言Rust视频教程-19装代码的箱子——面向对象之封装

接着上期继续说封装,为什么要把代码封装起来呢?因为要将代码分而治之,就像一个团队如果人数太多了就分成多个组,各个组的事务自己管理,组内解决不了的再上升到团队。就像用箱子把相关的代码装起来尽量跟外部做到最少的粘连,这也是面向对象编程中常提的高内聚低耦合,这样对一部分代码的修改升级改造不会影响其它代码。从而达到分而治之易于维护的目的。在Rust中我们可以使用module做为装代码的箱子。module也就是模块的意思。使用mod 关键字定义一个名称为trousers的module,module名称全小写跟首字母大小的Struct 类型Trousers区分开。在module名称后是一对大括号也就是我们装代码的地方了,我们把定义的Trousers类型和Brand枚举类型复制到大括号中。

mod trousers {                                                                                     
    #[derive(Debug)]
    pub enum Brand {
      A(String),
      B,
      C
    }
    #[derive(Debug)]
    pub struct Trousers {
        pub code: u32,
        pub brand: Brand,
            len: u8,
            create_date: String
    }
    impl Trousers {
       pub fn set_len(&mut self, len: u8) {
          if len >= 8 && len <= 10 {
           self.len = len;
          }
  
       }
       pub fn new(code: u32, brand: Brand, len: u8) -> Self {
         Trousers {
            code,
            brand,
            len,
            create_date : String::from("2022-2-22")
         }
       }
    }
  }

修改好后再运行下代码。
cargo run
出错了吧,找不到Trouser类型和Brand枚举类型了吧?因为我们把他们放module箱子里了,所以外面就看不到了。那外面如果需要使用module中的类型该怎么办呢? 在Rust中可以使用use关键字,这里我们使用use关键字声明我们需要使用trousers模块的裤子类型和品牌枚举类型。这样Rust就知道我们使用的裤子模块和品牌类型是trousers模块里的了。那Rust就可以找到我们的类型了。再运行看下效果。
cargo run
从输出的错误信息可以看出,Rust已经找到了Trousers和Brand类型,现在是告诉我们这俩个类型是模块私有的,外部不能访问。那怎么把这俩个类型变成外部可以访问的呢?
可以使用pub关键字,我们在Trousers类型和Brand枚举类型前添加pub关键字也就是public,声明他们是可以被外部访问的。在运行看下效果,这次已经不在说类型不可访问而是说属性和方法不能被外部访问。那我们也在属性和方法上添加pub关键字声明他们是可以被外部使用的。修改好后再运行看下效果,这次没有报错了吧,我们通过使用pub关键字把模块中的说有内容都设置成外部可以访问的了,也就是把箱子做成全透明的了。所以pub关键字一定要有选择的添加。从这个例子我们也可以看出,枚举类型的枚举值默认都是public的而Struct类型的属性和方法及类型关联方法默认都是private的也就是私有的不能被外部访问的。一个透明的箱子用处不大没有起到封装的效果是吧,我们做点体现箱子价值的事。
话说小胖穿长度为8到10的裤子,太短或太长都不行,所以我们在set_len函数里给添加上限制条件如果传递的长度值不在8到10之间我们就保持裤子的长度不变。也就是只有在8到10之间的数字才能设置成功。就不能放开len属性的访问权限了吧,不然想怎么改就怎么改,我们把len属性的pub关键字去掉,只能通过set len方法设置裤子的长度。我们运行看下效果。
cargo run
报错了吧?提示我们len属性已经私有化了外部不能访问了但这里还在试图访问len属性,是我们创建trousers_a的时候有设置len属性吧,我们把创建trousers_a的代码也改成通过调用类型关联函数new创建。在运行看下,这次没有报错了吧,这样就限制了外部对len属性的胡乱修改,箱子是不是就起点作用了。我们再来个需求,裤子还需要创建日期属性,那我们现在是不是可以只在箱子内部修改就可以了,创建日期我们可以去系统的当前日期吧,我们这里使用字符串表示一下子,在类型关联方法里设置当前日期,假如现在是2022年2月22号 ,我们只在箱子内部做了修改吧,我们运行下代码看有没有报错, 没有报错吧?!箱子是不有点用了。
当前箱子还是跟使用箱子的代码在一个代码文件里,是不是一不小心也会被破坏了啊,我们可以把箱子挪动到到另一个文件里,在src文件夹下新建lib.rs文件,把裤子模块移动到lib.rs文件中,注意这个文件名称是约定好的,不能随便改。移动好代码后,我们在运行下。报错了吧,因为我们把箱子换了个地方,所以Rust又找不到了,这里使用的use是一个相对路径,就是从使用代码的地方去找到箱子的路径,因为箱子的移动所以这个相对路径就不能用了,我们这里可以通过相对项目的路径查找到我们的箱子,项目的路径名称是什么呢?在我们的Cargo.toml文件里,这里配置的name rust_learn就是项目的启始路径名称,我们的trousers模块是在这个路径之下的,所以我们把路径改成rust_learn::trousers, 修改完成后再运行下代码,又报个错误吧?报trousers模块也是私有的不能被外部访问是吧,因为刚才在一个模块里,现在换到不同模块了,所以我们给trousers模块也加上pub关键字,让他变成外部可以访问的。在运行看下效果,这次没有报错了吧。
这一期我们学习了使用模块将代码封装起来,封装有俩层含义:一个是按照一定规则把代码组织到一起,一个是访问控制。我们还学习了将代码拆分到不同文件,使用模块是一层封装,使用不同的文件是不是又一层封装,以后我们还会使用不同的项目是不是又一层封装。使用use关键字引入模块,在使用use关键字时还可以使用as 关键字给模块、类型等起个新名字,这个主要用于解决同名冲突问题。就像我们班级里有俩个名字一样同学的都叫王强,为了方便区分我们就一个叫小王,一个叫大王。
我们演示一下子,把Brand类型重新命名为Bd类型,我们修改下相关代码,修改好后运行看下,代码依然可以正常执行吧?
另外大家可能还会遇到extern关键字,在rust 2015版本中当需要使用外部代码时需要先使用extern引入,在2018版本后这个基本就不用了,见了认识就好。
大家可以把课程中的代码复现练习下,下一期我们讲面向对象编程的另一个重要特性——接口

内容根据视频整理,相应视频内容可访问

51cto学院:
51cto

免费进群交流

KeepLearning

If you have never made a mistake, you have never tried anything new.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一个不安分的程序员

祝您财源广进

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值