rust windows 交叉编译_Rust编程语言从入门到放弃

f91edf7755110b742a85dd81a12b1945.png

Rust 是一门系统编程语言(Systems Programming Language),兼顾安全(Safety)、性能(Speed)和并发(Concurrency)。Rust作为一门底层的系统编程语言,理论上,使用 C/C++ 的领域都可以使用Rust实现,例如对硬件需要精细控制的嵌入式编程、对性能要求极高的应用软件(数据库引擎、浏览器引擎,3D渲染引擎等)。相对于 C/C++ 的系统性缺陷(内存管理不当造成的安全漏洞),Rust通过所有权(Ownership)机制在编译期间确保内存安全,无需垃圾回收(Garbage Collection, GC),也不需要手动释放内存。

1. Hello World

1.1 安装 Rust

  • 在线安装
    • Windows:下载 rustup-init.exe,自动引导安装。
    • Linux:curl –proto ‘=https’ –tlsv1.2 -sSf https://sh.rustup.rs | sh
  • 离线安装
    • 下载独立安装包
    • Windows: 下载 .msi 文件,双击安装即可。
    • Linux:下载 .tar.gz 文件,tar -xvf xxx.tar.gz 解压后,执行 install.sh 即可。
  • 查看版本
$ rustc --versionrustc 1.39.0 (4560ea788 2019-11-04)$ cargo --versioncargo 1.39.0 (1c6ec66d5 2019-09-30)

1.2 第一个Rust程序

fn main() {    println!("Hello, world!");}

使用 fn 声明函数。与大部分编程语言一致,main() 是 Rust 程序的入口。println! 表示打印文本到控制台,! 表示这是一个宏(macro),而非一个函数(function)。

  • 保存为 hello_world.rs,rs 为 Rust 语言的后缀。
  • 编译:rustc hello_world.rs。
  • 执行:./hello_world(Linux),hello_world.exe(Windows)

尝试下 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!

1.3 使用 Cargo

为了方便之后的调试和学习,先介绍 Rust 内置的包管理和构建系统 Cargo,crates.io 是 Rust 的社区仓库。

  • 创建新项目:cargo new
  • 编译:cargo build
  • 运行:cargo run
  • 更新项目依赖:cargo update
  • 执行测试:cargo test
  • 生成文档:cargo doc
  • 静态检查:cargo check
  • 新建二进制(Binary/Executable)项目
$ 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!
  • 新建 Library 项目
$ cargo new tutu --lib$ cd tutu && tree├── Cargo.toml└── src    └── lib.rs
  • Cargo.toml 是工程的描述文件,包含 Cargo 所需的所有元信息。
  • src 放置源代码。
  • main.rs / lib.rs 是入口文件。

运行 cargo run 或 cargo build,可执行文件将生成在 target/debug/ 目录,运行 cargo build –release,可执行文件将生成在 target/release/ 。

2 基本概念

2.1 注释

/// 外部注释mod test {    // 行注释    /* 块注释 */}mod test {    //! 包/模块级别的注释    // ...}

///用于 mod 块外部,//!用于书写包/模块级别的注释注释支持 markdown 语法,使用 cargo doc 生成 HTML 文档。

2.2 变量

  • 局部变量

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;

2.3 函数

使用 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

2.4 基本数据类型

  • 布尔值(bool)
  • 字符(char)
  • 有符号整型(i8, i16, i32, i64, i128)
  • 无符号整型(u8, u16, u32, u64, u128)
  • 指针大小的有符号/无符号整型(isize/usize,取决于计算机架构,32bit 的系统上,isize 等价于i32)
  • 浮点数(f32, f64)
  • 数组(arrays),由相同类型元素构成,长度固定。
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 (非基本数据类型)。

  • 元组(tuples),由相同/不同类型元素构成,长度固定。
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!")

元组的长度也是不可变的,更新元组内元素的值时,需要与之前的值的类型相同。

  • 切片(slice),指向一段内存的指针。

切片并没有拷贝原有的数组,只是指向原有数组的一个连续部分,行为同数组。访问切片指向的数组/数据结构,可以使用&操作符。

let a: [i32; 4] = [1, 2, 3, 4];let b: &[i32] = &a; // 全部let c = &a[0..4]; // [0, 4)let d = &a[..]; // 全部let e =
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值