赞
踩
Rust 是一门系统编程语言(Systems Programming Language),兼顾安全(Safety)、性能(Speed)和并发(Concurrency)。Rust作为一门底层的系统编程语言,理论上,使用 C/C++ 的领域都可以使用Rust实现,例如对硬件需要精细控制的嵌入式编程、对性能要求极高的应用软件(数据库引擎、浏览器引擎,3D渲染引擎等)。相对于 C/C++ 的系统性缺陷(内存管理不当造成的安全漏洞),Rust通过所有权(Ownership)机制在编译期间确保内存安全,无需垃圾回收(Garbage Collection, GC),也不需要手动释放内存。
$ rustc --versionrustc 1.39.0 (4560ea788 2019-11-04)$ cargo --versioncargo 1.39.0 (1c6ec66d5 2019-09-30)
fn main() { println!("Hello, world!");}
使用 fn 声明函数。与大部分编程语言一致,main() 是 Rust 程序的入口。println! 表示打印文本到控制台,! 表示这是一个宏(macro),而非一个函数(function)。
尝试下 println! 更多的用法。
fn main() { println!("{}, {}!", "Hello", "world"); // Hello, world! println!("{0}, {1}!", "Hello", "world"); // Hello, world! println!("{greeting}, {name}!", greeting="Hello", name="world"); // Hello, world! let y = String::from("Hello, ") + "world!"; println!("{}", y); // Hello, world!}
以上代码将输出
Hello, world!Hello, world!Hello, world!Hello, world!
为了方便之后的调试和学习,先介绍 Rust 内置的包管理和构建系统 Cargo,crates.io 是 Rust 的社区仓库。
$ cargo new tutu --bin$ cd tutu && tree├── Cargo.toml└── src └── main.rs
在 main.rs 中写入
fn main() { println!("Hello, Cargo!");}
在项目目录下执行 cargo run
$ cargo run tutu git:(master) ✗ cargo run Compiling tutu v0.1.0 (/xxx/demo/tutu) Finished dev [unoptimized + debuginfo] target(s) in 0.49s Running `target/debug/tutu`Hello, Cargo!
$ cargo new tutu --lib$ cd tutu && tree├── Cargo.toml└── src └── lib.rs
运行 cargo run 或 cargo build,可执行文件将生成在 target/debug/ 目录,运行 cargo build –release,可执行文件将生成在 target/release/ 。
/// 外部注释mod test { // 行注释 /* 块注释 */}mod test { //! 包/模块级别的注释 // ...}
///用于 mod 块外部,//!用于书写包/模块级别的注释注释支持 markdown 语法,使用 cargo doc 生成 HTML 文档。
Rust 中变量默认是不可变的(immutable),称为变量绑定(Variable bindings),使用 mut 标志为可变(mutable)。
let 声明的变量是局部变量,声明时可以不初始化,使用前初始化即可。Rust是静态类型语言,编译时会检查类型,使用let声明变量时可以省略类型,编译时会推断一个合适的类型。
// 不可变let c;let a = true;let b: bool = true;let (x, y) = (1, 2);c = 12345;// 可变let mut z = 5;z = 6;
rust 中可用 static 声明全局变量。用 static 声明的变量的生命周期是整个程序,从启动到退出,它占用的内存空间是固定的,不会在执行过程中回收。另外,static 声明语句,必须显式标明类型,不支持类型自动推导。全局变量在声明时必须初始化,且须是简单赋值,不能包括复杂的表达式、语句和函数调用。
// 静态变量(不可变)static N: i32 = 5;// 静态变量(可变)static mut N: i32 = 5;
const 的生命周期也是整个程序,const 与 static 的最大区别在于,编译器并不一定会给 const 常量分配内存空间,在编译过程中,它很可能会被内联优化,类似于C语言的宏定义。
const N: i32 = 5;
使用 fn 声明函数。
fn main() { println!("Hello, world!");}
参数需要指定类型
fn print_sum(a: i8, b: i8) { println!("sum is: {}", a + b);}
默认返回值为空(),如果有返回值,需要使用->指定返回类型。
fn plus_one(a: i32) -> i32 { a + 1 // 等价于 return a + 1,可省略为 a + 1}
可以利用元组(tuple)返回多个值
fn plus_one(a: i32) -> (i32, i32) { (a, &a + 1)}fn main() { let (add_num, result) = plus_one(10); println!("{} + 1 = {}", add_num, result); // 10 + 1 = 11}
函数指针也可以作为变量使用
let b = plus_one;let c = b(5); //6
let a = [1, 2, 3]; // a[0] = 1, a[1] = 2, a[2] = 3let mut b = [1, 2, 3];let c: [int; 3] = [1, 2, 3]; // [类型; 数组长度]let d: ["my value"; 3]; //["my value", "my value", "my value"];let e: [i32; 0] = []; // 空数组println!("{:?}", a); //[1, 2, 3]
数组(arrays)的长度是可不变的,动态/可变长数组可以使用 Vec (非基本数据类型)。
let a = (1, 1.5, true, 'a', "Hello, world!");// a.0 = 1, a.1 = 1.5, a.2 = true, a.3 = 'a', a.4 = "Hello, world!"let b: (i32, f64) = (1, 1.5);let (c, d) = b; // c = 1, d = 1.5let (e, _, _, _, f) = a; //e = 1, f = "Hello, world!", _ 作为占位符使用,表示忽略该位置的变量let g = (0,); // 只包含一个元素的元组let h = (b, (2, 4), 5); //((1, 1.5), (2, 4), 5)println!("{:?}", a); //(1, 1.5, true, 'a', "Hello, world!")
元组的长度也是不可变的,更新元组内元素的值时,需要与之前的值的类型相同。
切片并没有拷贝原有的数组,只是指向原有数组的一个连续部分,行为同数组。访问切片指向的数组/数据结构,可以使用&操作符。
let a: [i32; 4] = [1, 2, 3, 4];let b: &[i32] = &a; // 全部let c = &a[0..4]; // [0, 4)let d = &a[..]; // 全部let e =
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。