Rust 浅尝辄止

大概是今年初的时候第一次听说 Mozilla 发布的新编程语言 Rust ,作者是 JavaScript 之父。

但由于个人一直对 JavaScript / HTML5 这些 Web 前端的东西不感冒(现在也就写 blog 用下 MarkDown / HTML ),所以当时也没怎么去深入了解。

后来偶然了解到,Rust 和 Golang 一样标榜的是高并发、系统编程语言,于是渐渐产生了兴趣。

特别是在知乎上一个相关问题下看到的回答,更是激发了我去学习 Rust :

除了 library 或 keyword 缩写比较恶心以外, 其他所有地方完爆 Go.

Rust 官网提到的大多数 feature 其实 Golang 都有:

  • 并发、高性能;

  • 闭包,高阶函数;

  • 类型推导;

  • 函数多值返回;

  • C-binding ( Golang 有 cgo );

不过据目前所了解的,它们二者至少有三方面差异:

  • Rust 支持泛型,Golang 不支持;

  • Rust 没有 GC 机制,Golang 支持 GC 并且可配置;

  • 二者并发模型不同,这个因为还没有深入研究过,具体参考知乎上的这个问题

好了,还是先来通过 tutorial 正式体验下吧。

环境搭建很简便,不用像 Golang 一样需要配置 GOPATH 环境变量。直接下载二进制包,运行 install.sh 就行了,然后运行 rustc 命令编译为二进制可执行文件。

Hello World

这个确实比 Golang 还简洁,不用声明 package ,也不用 import :

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

不过正如知乎上那位说的,这 fn 的缩写真够猥琐的,为了提升逼格简直不择手段啊。

变量声明、定义、打印

let 大致相当于 Golang 中的 var ,用于声明变量,不过如果值会改变需要加 mut 关键字:

let lang = "Rust";
let mut count = 0i;

type 用法也和 Golang 中类似,用于定义类型,不过中间多了一个 = :

type MyType = int;

println 函数用法也类似,不过变量占位符并不像大多数语言那样用 % ,而是用 {} :

println!("Hello, {}!", lang);

函数

除了关键字缩写差两个字母,返回值前面多个 -> ,其他基本和 Golang 中一样:

fn is_ten(x: int) -> bool {
	x == 10
}

不过这里有个特性,就是可以省略 return ,默认会把表达式的值作为返回值。

条件控制

基本和其他语言用法一样,唯一创新之处就是可以直接将整个代码块的值赋给变量,确实比三元运算符更方便:

let x =
		if x % 2 == 0 {
			1i
		} else {
			0i
		};

模式匹配

类似 Golang 中的 switch ,而且同样是不贯穿的,不需要 break ;

多个相同处理方式的条件可用 | 连接,默认条件用 _ 表示;

最后同样可将整个代码块赋值给变量:

let month = 7i;
let max_day =
		match month {
			2 => 28i,
			4 | 6 | 9 | 11 => 30i,
			_ => 31i
		};

循环控制

这方面 Golang 显然更简洁,for / for in 搞定一切。Rust 分为 while / loop / for in

fn use_while() {
	let mut count = 0i;
	while count < 10 {
		println!("count: {}", count);
		count += 1;// '++' operation is not supported.
	}
}

fn use_loop() {
	let mut x = 100u;
	loop { //like 'while(true)'
		x -= 10;
		println!("x: {}", x);
		if x <= 0 {
			break;
		}
	}
}

fn use_for_in() {
	for y in range(0u, 10) {
		println!("y: {}", y);
	}
	let str = "RincLiu";
	for chr in str.chars() {
		println!("{}", chr);
	}
}

结构体

和 Golang 同样作为类 C 的系统编程语言,结构体这东西肯定少不了。

用法也大同小异,就是定义结构体更简洁,不需要 typedef / type 之类的关键字声明:

struct Location {
	longitude: f64,
	latitude: f64
}

fn use_struct() {
	let mut myLocation = Location { longitude: 121.3581038898, latitude: 31.2198830738 };
	myLocation.latitude += 1.0;
	println!("My location: {}, {}", myLocation.longitude, myLocation.latitude );
}

枚举

很不幸,在这里踩坑了。下面这段代码中,枚举成员使用了结构体类型:

enum Shape {
	Circle { center: Point, radius: f64 },
	Retangle { top_left: Point, bottom_right: Point }
}

struct Point {
	x: f64,
	y: f64
}

fn area(shape: Shape) -> f64 {
	match shape {
		Circle { radius: radius, .. } => f64::consts::PI * square(radius),
		Retangle { top_left: top_left, bottom_right: bottom_right } => {
			(bottom_right.x - top_left.x) * (top_left.y - bottom_right.y)
		}
	}
}

fn use_enum() {
	let c = Point { x: 0, y: 0};
	let r = 12345.67890;
	let circie = Circle { center: c, radius: r};
	println!("Circle's area: {}", area(circle));
}

居然编译不过,提示这是个实验性的 feature ,可能有 bug :

tutorial 文档上说编译器暂时不支持:

manual 文档上说不确定是否会被保留,所以被隐藏:

果然是还没定型的、不成熟的新语言,就这程度真没人敢用。

虽然 Golang 只能通过 constiota 实现简单的枚举,但至少不会把这种处于实验阶段的 feature 放出来。

好吧,对于 Rust 的学习先暂时到此为止了,当然以后还是会持续关注。