找回密码
 立即注册
首页 资源区 代码 rust学习二十.10、RUST高级类型之新类型模式和类型别名 ...

rust学习二十.10、RUST高级类型之新类型模式和类型别名

公西颖初 前天 15:19
这两个内容都比较容易理解。
一、新类型(newtype)模式

注意,这里说的是一种编程模式,不是说有一个叫newtype的类型。
这种编程模式的含义:为某个类型作个封装,构建一个新的类型,以便绕过某些束缚,从而达成特定目的。
目的如下:
a.用于抽象掉一些类型的实现细节
b.可以隐藏其内部的泛型类型
c.实现曲线救国
一个典型的例子,利用新类型绕过孤儿规则。
二、类型别名

语法
type  xxx=现有的类型
看起来有点像特质中的关联类型定义。
附:特质关联类型实现示例
  1. impl Fight for Person {
  2.     type Item = Animal;
  3.     fn attack(&self, other: &self::Item) {
  4.         println!(
  5.             "{}岁{}(性别:{}) 攻击了 {}岁{}",
  6.             self.age,
  7.             self.name,
  8.             self.sex,
  9.             other.age,
  10.             other.name
  11.         );
  12.     }
  13.     fn defend<T: Danger>(&self, danger: &T) {
  14.         println!("{},{}岁{}(性别:{}) 奋起并力图战胜它们",danger.happen(), self.age, self.name, self.sex);
  15.     }
  16. }
复制代码
要点
a.简化类型书写
b.使得代码更容易阅读
c.也更方便维护,例如如果许多方法都要求用同个类型,那么这样定义之后就不容易搞错,
  作用上和java中定义的枚举常量一个道理。
在rust的标准库中,有不少的类型别名,例如Result等。
定义说明
a.可以为别名定义别名
b.没有明确的别名层级限定,意思就是你定义了别名a,然后基于a定义b,依次类推,可以定义type n=m..  .有多少层级限定不知道,不过定义个2次应该没有问题的。
 
rust的类型别名是一种类似Microsoft SqlServer自定义类型的东西。
在 SQL Server 中,可以通过 用户定义数据类型(User-Defined Data Types, UDT) 创建自定义类型,本质上是基于系统数据类型的别名,并附加约束或默认值。
例如:
  1. -- 创建类型:限制长度并校验格式
  2. CREATE TYPE dbo.Email
  3. FROM VARCHAR(255)
  4. NOT NULL
  5. WITH CHECK (CHARINDEX('@', value) > 0);
  6. -- 使用类型
  7. CREATE TABLE Users (
  8.     UserID INT PRIMARY KEY,
  9.     UserEmail dbo.Email
  10. );
  11. -- 测试插入
  12. INSERT INTO Users VALUES (1, 'test@example.com');  -- 成功
  13. INSERT INTO Users VALUES (2, 'invalid-email');     -- 失败,触发 CHECK 约束
复制代码
只要做过数据库设计,就知道这个东西多好用! 好记、容易保证相同的属性使用相同的类型、维护也非常容易。
如果修改了type,就会发现有的时候,这真是一个绝妙的注意。
这种好东西在postgresql和mysql(8以上)都有类似的实现。
 
所以,毫无疑问,在rust中这是一个绝妙主意,因为我们都知道rust的类型之复杂丑陋是出名的,有的时候让人心烦,又会耗费很多时间打字,而又了别名就会在某些情况下,大大改善这个现象。
 
三、新类型示例
  1. use student::*;
  2. use teacher::*;
  3. fn main() {
  4.     let lml = Studentinfo {
  5.         name: String::from("lml"),
  6.         age: 18,
  7.         gender: String::from("女"),
  8.         no: String::from("12101"),
  9.     };
  10.     print_student(&lml);
  11.     lml.learn();
  12.     lml.sleep();
  13.     let lu = Teacherinfo {
  14.         name: String::from("lu"),
  15.         age: 46,
  16.         gender: String::from("男"),
  17.         position: String::from("教研组长"),
  18.     };
  19.     lu.teach_student(&lml);
  20.     print_teacher(&lu);
  21.     let _me = Box::new(String::from("中国"));
  22.     let my_lu = MyTeacherinfo(lu);
  23.     my_lu.print();
  24. }
  25. struct MyTeacherinfo(Teacherinfo);
  26. impl Print for MyTeacherinfo {
  27.     fn print(&self) {
  28.         println!(
  29.             "教师基本信息-姓名:{},年龄:{},性别:{},职位:{}",
  30.             self.0.name, self.0.age, self.0.gender, self.0.position
  31.         );
  32.     }
  33. }
复制代码
本例中,Teacherinfo是外部包类型。
四、类型别名示例

[code]struct Person {    name: String,    age: u8,}type Teacher = Person;type Student = Person;type GoodPeople = Student;type Thunk = Box
您需要登录后才可以回帖 登录 | 立即注册