【multipass】一个好用的跨平台虚拟机
multipass
是一个很好用的虚拟机软件,基于它能够快速创建出需要的虚拟机环境。
很多语言中都有闭包,有的叫匿名函数,有的叫 lambda
函数,用一个最简单的例子演示闭包,例如 sort_by_key
传入的就是一个闭包函数:
1 | struct City { |
Rust
中的每一个引用都有其生命周期(lifetime),也就是引用保持有效的作用域。大部分时候生命周期是隐含并可以推断的,正如大部分时候类型也是可以推断的一样。但有些时候,Rust
需要我们使用泛型生命周期参数来注明他们的关系,这样就能确保运行时实际使用的引用绝对是有效的。
Rust
是一门赋予每个人构建可靠且高效软件能力的语言。
Rust
相比其他语言,具有显著的特点,尤其是:
性能高;Rust
速度惊人且内存利用率极高。由于没有运行时和垃圾回收,它能够胜任对性能要求特别高的服务,可以在嵌入式设备上运行,还能轻松和其他语言集成。
高可靠;Rust
丰富的类型系统和所有权模型保证了内存安全和线程安全,让您在编译期就能够消除各种各样的错误。
极具生产力;Rust
拥有出色的文档、友好的编译器和清晰的错误提示信息, 还集成了一流的工具——包管理器和构建工具, 智能地自动补全和类型检验的多编辑器支持, 以及自动格式化代码等等。
HTTPS
实现原理:
以下使用 docker
准备学习环境。
centos
的最新镜像:docker image pull centos
docker volume create centos
docker run -d -it -v centos:/workdir --name centos centos /bin/bash
docker exec -it centos /bin/bash
API
服务,通过Openresty
直接访问数据库;学习 rust
的第一步当然是安装,在 rust
中,工具链的安装,升级版本切换都是由 rustup
来完成的。rust
的工具链分布在三个不同的 channel
:stable
,beta
和 nightly
。
可以将 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
镜像使用帮助
1 | [source.crates-io] |
也推荐的字节跳动的 Rustup
镜像和 crates.io
镜像,具体请看 https://rsproxy.cn/
。
交叉编译就是跨平台编译,例如在 window
下编译程序的linux版本,或者在 x86_64
平台下编译 aarch64
版本。跨平台编译在Go语言中非常方便,得益于Go语言汇编器的设计。
本文展示如何在 Apple M1
的平台下编译 Linux aarch64
的应用程序。
Apple M1
:
1 | ~/WORKDIR/gamelife1314.github.io on source! ⌚ 13:15:25 |
linux aarch64
:
1 | ubuntu@vm-docker:~$ gcc -dumpmachine |
下面是在 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 | true ,false |
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) |
闭包 | ` |
在编程语言的内存使用中,我们经常遇到什么时候释放内存以及如何确定访问的内存是否已被释放等问题。对于内存管理方式,存在着两大阵营:
一种是以 Python
,JavaScript
, Ruby
,Java
, C#
,以及 Go
等为代表的拥有垃圾回收器的语言,垃圾回收器在对象不再被访问时,会释放对象所持有的内存。这种方式对开发者友好,因为我们不用太多关心内存的申请和释放,但是这意味着将对象释放的权利交给了垃圾回收器,对于理解什么时候释放内存会是一个较大的挑战。
另一种是以 C
和 C++
为代表的语言,它们将内存的申请和回收完全交给了开发者,这造成过很多致命的问题,悬垂指针,访问已释放内存以及多重释放等问题;
Rust
旨在既安全又高效,因此这两种方案都不能接受,但如果有更好的方案,估计早就有人做了。Rust
通过限制程序使用指针的方式打破了这种非得妥协的僵局。Rust
的做法激进,但这成了它成功的基础,尽管有诸多限制,但使用起来依然足够灵活。