UMBRELLA

未雨绸缪,举重若轻

很多语言中都有闭包,有的叫匿名函数,有的叫 lambda 函数,用一个最简单的例子演示闭包,例如 sort_by_key 传入的就是一个闭包函数:

1
2
3
4
5
6
7
8
9
10
struct City {
name: String,
population: i64,
country: String,
}

fn main() {
let mut cities = Vec::<City>::new();
cities.sort_by_key(|city| -city.population)
}
阅读全文 »

Rust 中的每一个引用都有其生命周期(lifetime),也就是引用保持有效的作用域。大部分时候生命周期是隐含并可以推断的,正如大部分时候类型也是可以推断的一样。但有些时候,Rust 需要我们使用泛型生命周期参数来注明他们的关系,这样就能确保运行时实际使用的引用绝对是有效的。

阅读全文 »

Rust 是一门赋予每个人构建可靠且高效软件能力的语言。

Rust 相比其他语言,具有显著的特点,尤其是:

  1. 性能高;Rust 速度惊人且内存利用率极高。由于没有运行时和垃圾回收,它能够胜任对性能要求特别高的服务,可以在嵌入式设备上运行,还能轻松和其他语言集成。

  2. 高可靠;Rust 丰富的类型系统和所有权模型保证了内存安全和线程安全,让您在编译期就能够消除各种各样的错误。

  3. 极具生产力;Rust 拥有出色的文档、友好的编译器和清晰的错误提示信息, 还集成了一流的工具——包管理器和构建工具, 智能地自动补全和类型检验的多编辑器支持, 以及自动格式化代码等等。

阅读全文 »

环境准备

以下使用 docker 准备学习环境。

  1. 先拉取centos的最新镜像:docker image pull centos
  2. 创建一个数据卷用于存放容器中产生的文件:docker volume create centos
  3. 启动我们的容器:docker run -d -it -v centos:/workdir --name centos centos /bin/bash
  4. 进入我们的容器:docker exec -it centos /bin/bash

Nginx 的主要应用场景

  1. 静态资源服务,即通过本地文件系统提供服务;
  2. 反向代理服务,提供缓存,负载均衡功能;
  3. API服务,通过Openresty直接访问数据库;
阅读全文 »

学习 rust 的第一步当然是安装,在 rust 中,工具链的安装,升级版本切换都是由 rustup 来完成的。rust 的工具链分布在三个不同的 channelstablebetanightly

可以将 rustup 看做 rust 的版本管理器,方便我们在不同的 channel 之间进行切换。 在国内 rust 的相关网站是没有被 GFW 屏蔽的,但是访问速度还是很慢。好在国内有很多镜像源,例如,我这里使用的是中国科学技术大学的镜像,配置的话只需要添加两个环境变量:

  • export RUSTUP_DIST_SERVER=https://mirrors.ustc.edu.cn/rust-static
  • export RUSTUP_UPDATE_ROOT=https://mirrors.ustc.edu.cn/rust-static/rustup

rustup 的安装我们依然使用官方的方式:

curl –proto ‘=https’ –tlsv1.2 -sSf https://sh.rustup.rs | sh

执行结束之后,应该能看到下面这样的信息,而且会默认安装 nightly(每日构建)版本:

我们可以顺手配置以下 cargo 的镜像地址,参考自 中科大 Rust Crates 镜像使用帮助

~/.cargo/config
1
2
3
4
5
6
[source.crates-io]
registry = "https://github.com/rust-lang/crates.io-index"
replace-with = 'ustc'

[source.ustc]
registry = "git://mirrors.ustc.edu.cn/crates.io-index"

也推荐的字节跳动的 Rustup 镜像和 crates.io 镜像,具体请看 https://rsproxy.cn/

阅读全文 »

交叉编译就是跨平台编译,例如在 window 下编译程序的linux版本,或者在 x86_64 平台下编译 aarch64 版本。跨平台编译在Go语言中非常方便,得益于Go语言汇编器的设计。

MacOS 交叉编译 Linux 程序

本文展示如何在 Apple M1 的平台下编译 Linux aarch64 的应用程序。

  • Apple M1

    1
    2
    3
    4
    5
    6
    7
    ~/WORKDIR/gamelife1314.github.io on  source! ⌚ 13:15:25
    $ uname -pvm
    Darwin Kernel Version 21.4.0: Fri Mar 18 00:46:32 PDT 2022; root:xnu-8020.101.4~15/RELEASE_ARM64_T6000 arm64 arm

    ~/WORKDIR/gamelife1314.github.io on  source! ⌚ 13:15:38
    $ gcc -dumpmachine
    arm64-apple-darwin21.4.0
  • linux aarch64

    1
    2
    3
    4
    5
    ubuntu@vm-docker:~$ gcc -dumpmachine
    aarch64-linux-gnu
    ubuntu@vm-docker:~$ uname -pvm
    #40-Ubuntu SMP Mon Mar 7 08:06:10 UTC 2022 aarch64 aarch64
    ubuntu@vm-docker:~$
阅读全文 »

下面是在 Rust 中会看到的类型的总结,展示了Rust的基本类型,标准库中一些非常常见的类型,以及一些用户定义类型的例子。

Type Description Values
i8, i16, i32, i64, i128 u8, u16, u32, u64, u128 给定宽度的有符号和无符号整数 42,-5i8, 0x400u16, 0o100i16, 20_922_789_888_000u64, b'*'
isize, usize 有符号整数和无符号整数, 与计算机上的地址大小相同(32位或64位) 137, -0b0101_0010isize, 0xffff_fc00usize
f32, f64 IEEE浮点数,单精度和双精度 1.61803, 3.14f32, 6.0221e23f64
bool Boolean truefalse
char Unicode字符,32位宽 '*', '\n', '字', '\x7f', '\u{CA0}'
(char, u8, i32) Tuple:允许混合类型 ('%', 0x7f, -1)
() 空元组 ()
struct S { x: f32, y: f32 } 字段带名称的复合结构 S { x: 120.0, y: 209.0 }
struct T (i32, char); Tuple-like struct T(120, 'X')
struct E; Unit-like struct; has no fields E
enum Attend { OnTime, Late(u32) } 枚举 Attend::Late(5), Attend::OnTime
Box<Attend> Box:拥有指向堆中的值的指针 Box::new(Late(15))
&i32, &mut i32 共享引用和可变引用:非拥有指针,不能比它们的引用活得更久 &s.y, &mut v
String 动态大小的UTF-8字符串 "ラーメン: ramen".to_string()
&str Reference to str: non-owning pointer to UTF-8 text "そば: soba", &s[0..12]
[f64; 4], [u8; 256] 数组,固定长度,元素同类型 [1.0, 0.0, 0.0, 1.0], [b' '; 256]
Vec<f64> 变长Vector,元素同类型 vec![0.367, 2.718, 7.389]
&[u8],&mut [u8] slice的引用:对数组或vector的一部分的引用,包括指针和长度 &v[10..20], &mut a[..]
Option<&str> 可选值,要么是 None,要么是 Some(v) Some("Dr."), None
Result<u64, Error> 可能失败的操作结果,成功就是 Ok(v),失败则是:Err(e) Ok(4096), Err(Error::last_os_error())
&dyn Any, &mut dyn Read Trait对象:引用任何实现了给定方法集的值 value as &dyn Any,&mut file as &mut dyn Read
fn(&str) -> bool 函数指针 str::is_empty
(Closure types have no written form) 闭包 `
阅读全文 »

在编程语言的内存使用中,我们经常遇到什么时候释放内存以及如何确定访问的内存是否已被释放等问题。对于内存管理方式,存在着两大阵营:

  • 一种是以 PythonJavaScriptRubyJavaC#,以及 Go 等为代表的拥有垃圾回收器的语言,垃圾回收器在对象不再被访问时,会释放对象所持有的内存。这种方式对开发者友好,因为我们不用太多关心内存的申请和释放,但是这意味着将对象释放的权利交给了垃圾回收器,对于理解什么时候释放内存会是一个较大的挑战。

  • 另一种是以 CC++ 为代表的语言,它们将内存的申请和回收完全交给了开发者,这造成过很多致命的问题,悬垂指针,访问已释放内存以及多重释放等问题;

Rust旨在既安全又高效,因此这两种方案都不能接受,但如果有更好的方案,估计早就有人做了。Rust 通过限制程序使用指针的方式打破了这种非得妥协的僵局。Rust的做法激进,但这成了它成功的基础,尽管有诸多限制,但使用起来依然足够灵活。

阅读全文 »
0%