链表简介链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。
简介普通的队列是一种先进先出的数据结构,元素在队列尾追加,而从队列头删除。在优先队列中,元素被赋予优先级。当访问元素时,具有最高优先级的元素最先删除。优先队列具有最高级先出 (largest-in,first-out)的行为特征。优先队列是0个或多个元素的集合,每个元素都有一个优先权或值,对优先队列执行的操作有:查找;插入一个新元素;删除。
二叉树简介在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。二叉查找树的子节点与父节点的键一般满足一定的顺序关系,习惯上,左节点的键少于父亲节点的键,右节点的键大于父亲节点的键。
队列简介队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。队列中没有元素时,称为空队列。在队列的形成过程中,可以利用线性链表的原理,来生成一个队列。
栈简介栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表。它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。
本章讲解如何使用 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 竟然连这个特性都集成在语言基础特性中,真的是一门很重视工程性的语言。下面直接说明如何使用。
程序测试是一种找到缺陷的有效方式,但是它对证明没有缺陷却无能为力。Edsger W. Dijkstra, "The Humble Programmer" (1972)作为软件工程质量保障体系的重要一环,测试是应该引起我们充分注意并重视的事情。前面说过,Rust 语言的设计集成了最近十多年中总结出来的大量最佳工程实践,而对测试的原生集成也正体现了这一点。下面来看 Rust 是怎么设计测试特性的。
本章讲解 Rust 中内建的测试与评测相关知识。
我们在使用toml描述文件对项目进行配置时,经常会遇到项目版本声明及管理的问题,比如:[package]name = "libevent_sys"version = "0.1.0"[dependencies]libc = "0.2"这里package段落中的version字段的值,以及dependencies段落中的libc字段的值,这些值的写法,都涉及到语义化版本控制的问题。语义化版本控制是用一组简单的规则及条件来约束版本号的配置和增长。
本章将介绍Rust编译器的参数。Rust编译器程序的名字是rustc,使用它的方法很简单:$ rustc [OPTIONS] INPUT其中,[OPTIONS]表示编译参数,而INPUT则表示输入文件。而编译参数有以下可选:-h, --help - 输出帮助信息到标准输出;--cfg SPEC - 传入自定义的条件编译参数,使用方法如fn main() { if cfg!(hello) { println!("world!");
属性(Attribute)是一种通用的用于表达元数据的特性,借鉴ECMA-334(C#)的语法来实现ECMA-335中描述的Attributes。属性只能应用于Item(元素、项),例如 use 声明、模块、函数等。元素在Rust中,Item是Crate(库)的一个组成部分。
本章将介绍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) ->
上一章讲述了如何从rust中调用c库,这一章我们讲如何把rust编译成库让别的语言通过cffi调用。调用约定和mangle正如上一章讲述的,为了能让rust的函数通过ffi被调用,需要加上extern "C"对函数进行修饰。但由于rust支持重载,所以函数名会被编译器进行混淆,就像c++一样。因此当你的函数被编译完毕后,函数名会带上一串表明函数签名的字符串。
下文提到的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安装。
FFI(Foreign Function Interface)是用来与其它语言交互的接口,在有些语言里面称为语言绑定(language bindings),Java 里面一般称为 JNI(Java Native Interface) 或 JNA(Java Native Access)。
关注时代Java