好了,本书到这里也接近完结了。相信你一在学习了这么多内容的之后,一定跃跃欲试了吧?下面,我们将以代码为主,讲解几个利用std库,即标准库来做的例子。希望大家能从中学到一点写法,并开始自己的Rust之旅。注: 由于笔者的电脑是openSUSE Linux的,所以本章所有代码均只在 openSUSE Leap 42.1 && rustc 1.9.
本章讲解如何使用 Rust 进行一些常用数据结构的实现。实现的代码仅作示例用,并不一定十分高效。真正使用的时候,请使用标准库或第三方成熟库中的数据结构。
本章不讲解任何语言知识点,而是对 Rust 安全理念的一些总结性说明。安全,本身是一个相当大的话题。安全性,本身也需要一个局部性的定义。Rust 的定义中,凡是 可能 会导致程序内存使用出错的特性,都被认为是 不安全的(unsafe)。反之,则是 安全的(safe)。基于这种定义,C 语言,基本是不安全的语言(它是众多不安全特性的集合。
熟悉Java的同学肯定对Java的反射能力记忆犹新,同样的,Rust也提供了运行时反射的能力。但是,这里有点小小的不同,因为 Rust 不带 VM 不带 Runtime ,因此,其提供的反射更像是一种编译时反射。因为,Rust只能对 'static 生命周期的变量(常量)进行反射!举个例子我们会有这样的需求,去某些路径里加载配置文件。
空白每行不能超出99个字符。缩进只用空格,不用TAB。行和文件末尾不要有空白。空格二元运算符左右加空格,包括属性里的等号:#[deprecated = "Use `bar` instead."]fn foo(a: usize, b: usize) -> usize { a + b}在分号和逗号后面加空格:fn foo(a: Bar);MyStruct { foo: 3, bar: 4 }foo(bar, baz);
单元测试是用来校验程序的正确性的,然而,程序能正常运行后,往往还需要测试程序(一部分)的执行速度,这时,f就需要用到性能测试。通常来讲,所谓性能测试,指的是测量程序运行的速度,即运行一次要多少时间(通常是执行多次求平均值)。Rust 竟然连这个特性都集成在语言基础特性中,真的是一门很重视工程性的语言。下面直接说明如何使用。
本章讲解 Rust 中内建的测试与评测相关知识。
本章将介绍Rust编译器的参数。Rust编译器程序的名字是rustc,使用它的方法很简单:$ rustc [OPTIONS] INPUT其中,[OPTIONS]表示编译参数,而INPUT则表示输入文件。而编译参数有以下可选:-h, --help - 输出帮助信息到标准输出;--cfg SPEC - 传入自定义的条件编译参数,使用方法如fn main() { if cfg!(hello) { println!("world!");
本章将介绍Rust语言中的属性(Attribute)和编译器参数(Compiler Options)。
Rust可以让我们对某些运算符进行重载,这其中大部分的重载都是对std::ops下的trait进行重载而实现的。重载加法我们现在来实现一个只支持加法的阉割版复数:use std::ops::Add;#[derive(Debug)]struct Complex { a: f64, b: f64,}impl Add for Complex { type Output = Complex; fn add(self, other: Complex) ->
下文提到的ffi皆指cffi。Rust作为一门系统级语言,自带对ffi调用的支持。Getting Start引入libc库由于cffi的数据类型与rust不完全相同,我们需要引入libc库来表达对应ffi函数中的类型。在Cargo.toml中添加以下行:[dependencies]libc = "0.2.9"在你的rs文件中引入库:extern crate libc在以前libc库是和rust一起发布的,后来libc被移入了crates.io通过cargo安装。
本章开始讲解 Rust 中的 Unsafe 部分。
在消息传递之外,还存在一种广为人知的并发模型,那就是共享内存。其实如果不能共享内存,消息传递也是不能在不同的线程间传递消息,也谈不上在不同的线程间等待和通知了。共享内存是这一切得以发生的基础。如果查看源码,你会发现消息传递的内部实现就是借用了共享内存机制。
并发是什么?引用Rob Pike的经典描述:并发是同一时间应对多件事情的能力其实在我们身边就有很多并发的事情,比如一边上课,一边发短信;一边给小孩喂奶,一边看电视,只要你细心留意,就会发现许多类似的事。相应地,在软件的世界里,我们也会发现这样的事,比如一边写博客,一边听音乐;一边看网页,一边下载软件等等。显而易见这样会节约不少时间,干更多的事。
本章讲解 Rust 中,并发,并行,多线程编程的相关知识。
std::marker 模块中,有两个 trait:Send 和 Sync,它们与多线程安全相关。标记为 marker trait 的 trait,它实际就是一种约定,没有方法的定义,也没有关联元素(associated items)。仅仅是一种约定,实现了它的类型必须满足这种约定。一种类型是否加上这种约定,要么是编译器的行为,要么是人工手动的行为。
Borrowuse std::borrow::Borrow;Borrow 提供了一个方法 .borrow()。对于一个类型为 T 的值 foo,如果 T 实现了 Borrow<U>,那么,foo 可执行 .borrow() 操作,即 foo.borrow()。操作的结果,我们得到了一个类型为 &U 的新引用。Borrow 可以认为是 AsRef 的严格版本,它对普适引用操作的前后类型之间附加了一些其它限制。
std::convert 下面,还有另外两个 Trait,AsRef/AsMut,它们功能是配合泛型,在执行引用操作的时候,进行自动类型转换。这能够使一些场景的代码实现得清晰漂亮,大家方便开发。AsRefAsRef 提供了一个方法 .as_ref()。对于一个类型为 T 的对象 foo,如果 T 实现了 AsRef<U>,那么,foo 可执行 .as_ref() 操作,即 foo.as_ref()。
本章讲解 Rust 类型系统中的几个常见 trait。有 Into, From, AsRef, AsMut, Borrow, BorrowMut, ToOwned, Deref, Cow。
前面我们提到,Rust 通过其所有权机制,严格控制拥有和借用关系,来保证程序的安全,并且这种安全是在编译期可计算、可预测的。但是这种严格的控制,有时也会带来灵活性的丧失,有的场景下甚至还满足不了需求。因此,Rust 标准库中,设计了这样一个系统的组件:Cell, RefCell,它们弥补了 Rust 所有权机制在灵活性上和某些场景下的不足。同时,又没有打破 Rust 的核心设计。
关注时代Java