本期文章接上期继续讲述Rust语言中的数据类型,Rust自定义数据类型主要是通过下面这两个关键字来创建:

  1. 结构体( struct ): 定义一个结构体(structure)
  2. 枚举( enum ): 定义一个枚举类型(enumeration)

    其余的类型常量则可以通过 conststatic 来创建。

一、结构体

结构体有3种类型,使用 struct 关键字来创建:

  • 具名结构体,具名元组
  • 元组类型结构体
  • 空结构体,不带字段,在泛型中很有用

1.具名结构体

// 带有两个字段(field)的结构体
struct Point {
x: f32,
y: f32,
} // 结构体可以作为另一个结构体的字段
struct Rectangle {
p1: Point,
p2: Point,
}

具名结构体内部每个成员都有自己的名字和类型,内部的成员也可以是另一个结构体。

2.元组类型结构体

// 元组结构体
struct Pair(i32, u16, bool);

可以看作是一个有名字的元组,具体使用方法和一般的元组基本类似。

3.空结构体

struct D;

空结构体的内存占用为0。但是我们依然可以针对这样的类型实现它的“成员函数”。

下面是整个样例:

#[derive(Debug)]
struct Person<'a> {
name: &'a str,
age: u8,
} // 单元结构体
struct Nil; // 元组结构体
struct Pair(i32, f32); // 带有两个字段(field)的结构体
struct Point {
x: f32,
y: f32,
} // 结构体可以作为另一个结构体的字段
#[allow(dead_code)]
struct Rectangle {
p1: Point,
p2: Point,
} fn main() {
// 使用简单的写法初始化字段,并创建结构体
let name = "Peter";
let age = 27;
let peter = Person { name, age }; // 以 Debug 方式打印结构体
println!("{:?}", peter); // 实例化结构体 `Point`
let point: Point = Point { x: 0.3, y: 0.4 }; // 访问 point 的字段
println!("point coordinates: ({}, {})", point.x, point.y); // 使用结构体更新语法创建新的 point,这样可以用到之前的 point 的字段
let new_point = Point { x: 0.1, ..point }; // `new_point.y` 与 `point.y` 一样,因为这个字段就是从 `point` 中来的
println!("second point: ({}, {})", new_point.x, new_point.y); // 使用 `let` 绑定来解构 point
let Point { x: my_x, y: my_y } = point; let _rectangle = Rectangle {
// 结构体的实例化也是一个表达式
p1: Point { x: my_y, y: my_x },
p2: point,
}; // 实例化一个单元结构体
let _nil = Nil; // 实例化一个元组结构体
let pair = Pair(1, 0.1); // 访问元组结构体的字段
println!("pair contains {:?} and {:?}", pair.0, pair.1); // 解构一个元组结构体
let Pair(integer, decimal) = pair; println!("pair contains {:?} and {:?}", integer, decimal);
}

二、枚举

Rust的枚举(enum)类型,跟C语言的枚举有点接近,然而更强大,事实上是代数数据类型(Algebraic Data Type)。

//一个代表东南西北四个方向的枚举
enum Direction {
West,
North,
Sourth,
East,
}

Rust中的枚举实现的功能不止这些,例如还阔以枚举出其他类型数据,例如:

enum SpecialPoint {
Point {
x: i32,
y: i32,
},
Special(String),
}

如何使用枚举:和struct的成员访问符号.不同的是,枚举类型要想访问其成员几乎都要用到模式匹配。你可以写一个Direction::West,注意你绝对不能写成Direction.West。

样例:

// 该属性用于隐藏对未使用代码的警告。
#![allow(dead_code)] // 创建一个 `enum`(枚举)来对 web 事件分类。注意变量名和类型共同指定了 `enum`
// 取值的种类:`PageLoad` 不等于 `PageUnload`,`KeyPress(char)` 不等于
// `Paste(String)`。各个取值不同,互相独立。
enum WebEvent {
// 一个 `enum` 可以是单元结构体(称为 `unit-like` 或 `unit`),
PageLoad,
PageUnload,
// 或者一个元组结构体,
KeyPress(char),
Paste(String),
// 或者一个普通的结构体。
Click { x: i64, y: i64 }
} // 此函数将一个 `WebEvent` enum 作为参数,无返回值。
fn inspect(event: WebEvent) {
match event {
WebEvent::PageLoad => println!("page loaded"),
WebEvent::PageUnload => println!("page unloaded"),
// 从 `enum` 里解构出 `c`。
WebEvent::KeyPress(c) => println!("pressed '{}'.", c),
WebEvent::Paste(s) => println!("pasted \"{}\".", s),
// 把 `Click` 解构给 `x` and `y`。
WebEvent::Click { x, y } => {
println!("clicked at x={}, y={}.", x, y);
},
}
} fn main() {
let pressed = WebEvent::KeyPress('x');
// `to_owned()` 从一个字符串切片中创建一个具有所有权的 `String`。
let pasted = WebEvent::Paste("my text".to_owned());
let click = WebEvent::Click { x: 20, y: 80 };
let load = WebEvent::PageLoad;
let unload = WebEvent::PageUnload; inspect(pressed);
inspect(pasted);
inspect(click);
inspect(load);
inspect(unload);
}

其它

作为码农,服务器可以说跟我们简直不可分割啊,推荐几个自己亲身使用过的云服务器平台给大家,有需要小伙伴可以自行查看:

1.阿里云:https://www.aliyun.com/?source=5176.11533457&userCode=mszy7nm5

2.腾讯云:https://curl.qcloud.com/jgwhoTBS

Rust之旅 02.通过例子学习自定义类型的更多相关文章

  1. 数百个 HTML5 例子学习 HT 图形组件 – 3D建模篇

    http://www.hightopo.com/demo/pipeline/index.html <数百个 HTML5 例子学习 HT 图形组件 – WebGL 3D 篇>里提到 HT 很 ...

  2. 数百个 HTML5 例子学习 HT 图形组件 – 3D 建模篇

    http://www.hightopo.com/demo/pipeline/index.html <数百个 HTML5 例子学习 HT 图形组件 – WebGL 3D 篇>里提到 HT 很 ...

  3. 数百个 HTML5 例子学习 HT 图形组件 – 拓扑图篇

    HT 是啥:Everything you need to create cutting-edge 2D and 3D visualization. 这口号是当年心目中的产品方向,接着就朝这个方向慢慢打 ...

  4. HTML5 例子学习 HT 图形组件

    HTML5 例子学习 HT 图形组件 HT 是啥:Everything you need to create cutting-edge 2D and 3D visualization. 这口号是当年心 ...

  5. JavaScript之面向对象学习七(动态原型模式、寄生构造函数模式、稳妥构造函数模式创建自定义类型)

    一.动态原型模式 在面向对象学习六中的随笔中,了解到组合构造函数模式和原型模式创建的自定义类型可能最完善的!但是人无完人,代码亦是如此! 有其他oo语言经验的开发人员在看到独立的构造函数和原型时,很可 ...

  6. pytorch例子学习-DATA LOADING AND PROCESSING TUTORIAL

    参考:https://pytorch.org/tutorials/beginner/data_loading_tutorial.html DATA LOADING AND PROCESSING TUT ...

  7. 代码走查25条疑问 C# 跳转新的标签页 C#线程处理 .Net 特性 attribute 学习 ----自定义特性 看懂 ,学会 .NET 事件的正确姿势-简单版

    代码走查25条疑问   代码走查(Code Review) 是一个开发人员与架构师集中讨论代码的过程.通过代码走查可以提高代码的 质量,同时减少Bug出现的几率.但是在小公司中并没有代码走查的过程在这 ...

  8. 数百个 HTML5 例子学习 HT 图形组件 – WebGL 3D 篇

    <数百个 HTML5 例子学习 HT 图形组件 – 拓扑图篇>一文让读者了解了 HT的 2D 拓扑图组件使用,本文将对 HT 的 3D 功能做个综合性的介绍,以便初学者可快速上手使用 HT ...

  9. [原创]java WEB学习笔记67:Struts2 学习之路-- 类型转换概述, 类型转换错误修改,如何自定义类型转换器

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

随机推荐

  1. Docker部署ELK之部署logstash7.6.0(4)

    前言: logstash 和filebeat都具有日志收集功能,filebeat更轻量,占用资源更少,但logstash 具有filter功能,能过滤分析日志.一般结构都是filebeat采集日志,然 ...

  2. 模拟退火 Simulated annealing

    模拟退火 Simulated annealing 看看有空把图片完善一下好了 模拟退火算法的一些背景 既然要说模拟退火算法,就应该说一下模拟退火算法的背景,模拟退火算法是局部搜索算法的一种扩展,该算法 ...

  3. webpack 配置文件外置

    转自:https://www.jianshu.com/p/377bfd2d9034 1.问题初衷 解决问题的初衷,源于vue项目中公共路径在打包之后一旦遇到整体的路径更改就需要再次build一下. 如 ...

  4. SpringCloud升级之路2020.0.x版-20. 启动一个 Eureka Server 集群

    本系列代码地址:https://github.com/HashZhang/spring-cloud-scaffold/tree/master/spring-cloud-iiford 我们的业务集群结构 ...

  5. 题解 marshland

    传送门 是个最大费用可行流 这题的建边很毒瘤 首先有危险度的点肯定要拆点 关键在于其它点怎么办 如果拆了不好保证每个点只经过一次 不拆连网络流都跑不了 但仔细观察题面,不能不难(???)发现一个L中那 ...

  6. map中使用箭头函数遇到的坑

    箭头函数提供了更简洁和更短的语法,其中一个可用功能是可以将函数编写为具有隐式返回值的lambda表达式.这对于功能样式代码很方便,比如使用函数映射数组: const numbers = [1,2,3, ...

  7. C# WPF 后台调整怎样使用代码把指定控件的Z序调整到最前面呢?

    Panel.SetZIndex(rectangle1, 2); //把前台名称为rectangle1的矩形的ZIndex设置为2

  8. GAC

    GAC是什么?是用来干嘛的?GAC的全称叫做全局程序集缓存,通俗的理解就是存放各种.net平台下面需要使用的dll的地方.GAC的具体目录在windows/ assembly. 喜欢使用破解软件的朋友 ...

  9. 页面的跳转MVVM,带参数的传递

    主页面 -------------------------- <Page x:Class="CheckMemoryLeak.MainPage" xmlns="htt ...

  10. ArcGIS图层添加字段出现:“定义了过多字段”

    首先,我图层数据格式为mdb,也就是Access数据库 Access一个表最大支持255个字段,可是我的才添加第一个字段就出现"定义了过多字段"的错误 打开ArcMap添加字段也是 ...