Rust 还没到1.0,开发很快,请看官方文档
Rust的语法和其余C-family 语言很类似。html
像if
while
这类的控制结构和其余类c语言最大的不一样是Rust中不须要在条件加括号, 可是,代码块要用大括号。访问命名空间函数,变量要用::
程序员
简单的循环express
rustfn main() { /* A simple loop */ loop { // A tricky calculation if universe::recalibrate() { return; } } }
使用let
关键字建立局部变量,变量默认是不可变的。若是要建立可变变量使用 let mut
ide
let hi = "hi"; let mut count = 0; while count < 10 { println!("count is {}", count); count += 1; }
Rust 能够本身推断出变量的类型,固然咱们也能够在变量名后冒号加变量类型指定变量类型,
另外,static 变量须要在定义的时候指定类型。函数
static MONSTER_FACTOR: f64 = 57.8; let monster_size = MONSTER_FACTOR * 10.0; let monster_size: int = 50;
局部变量也能够覆盖以前的申明,好比上面的例子中monster_size
最开始是 f64
类型,
第二个monster_size 是 int
类型。编译代码的话,会有warningoop
hellworld.rs:27:6: 27:18 warning: unused variable: `monster_size`, #[warn(unused_variable)] on by default hellworld.rs:27 let monster_size = MONSTER_FACTOR * 10.0; ^~~~~~~~~~~~
waring 说 monster_size
这个变量未使用(这种状况通常是程序员程序写错了的)。
若是你想声明一个未使用的变量,用不想用waring,能够在变量前加一个下划线消除waring。
例如: let _monster_size = 50;
ui
Rust标识符以字母或者下划线开头,后边能够跟任意的字符序列,数字,或者下划线。
首选的代码风格是:对于函数,变量,模块名使用小写字母,使用下划线提升可读性,
自定义类型使用驼峰法。this
let my_variable = 100; type MyType = int; // primitive types are _not_ camel case
Rust和它的前辈好比C在语法上有一个显著的区别:许多在 C 中是语句的结构在 Rust 中是表达式,这让代码能够更加简洁。例如,你或许想写一段这样的代码:指针
let price; if item == "salad" { price = 3.50; } else if item == "muffin" { price = 2.25; } else { price = 2.00; }
可是,在Rust里,你没必要重复写price:code
let price = if item == "salad" { 3.50 } else if item == "muffin" { 2.25 } else { 2.00 };
两段代码彻底等价:都是经过条件判断为变量 price 赋值。注意第二段代码中没有分号。这是重点:在大括号括起来的代码块中,最后一个语句省略分号,会将最后语句的值做为此代码块的返回值。
换句话说,Rust中的分号将忽略一个表达式的值。因此若是 if 分支是 { 4;},上例中的 price 将被赋值为 () (nil 或者 void)。可是没有这个分号,每一个分支将有一个不一样的值,而且 price 被赋予选定分支的值。
归纳一下就是,除了声明(使用 let 声明变量,fn 声明函数,任何顶层命名的项,如 traits, 枚举类型 和static )的都是一个表达式,包括函数体。
fn is_four(x: int) -> bool { // 不须要return,最后一个表达式的结果,做为返回值 x == 4 }
整形有 int 和 uint,是有符号整型和无符号整型,其余变体,8位,16位,32位,64位等。能够写成10进制的形式(144),16进制 (0x90)八进制 (0o70)或者二进制(0b10010000)
,每一个整数类型都有相应的后缀,能够用来指示字面量类型:i 表明int、u 表明uint、i8 表明i8类型。
若是没有给整型指明后缀,Rust将根据上下文中的类型注释和函数签名来推断整数类型。若是实在没有任何类型信息,Rust将假定这个没有后缀的字面量为int型。
let a = 1; // `a` 是 `int` let b = 10i; // `b` 是 `int`, 因为 `i` 后缀 let c = 100u; // `c` 是 `uint` let d = 1000i32; // `d` 是 `i32`
有两种浮点数类型:f32和f64。浮点数写成0.0、1e6 或者2.1e-4这些形式。和整数同样,浮点数字面量能够推导出正确的类型。后缀f32 和f64 能够用来指定一个字面量的类型。
关键字true 和false 指定bool 类型字面量。
字符,char 类型,是4个字节存储的Unicode码点,写在两个单引号间,如'x',和在C 中同样,Rust使用反斜杠做为字符转义符,如\n,\r 以及\t。字符串字面量,写在两个双引号之间,容许使用一样的转义符。
另外一方面,原始字符串(raw string)不处理任何转义序列。它们这样写:r##"blah"##
,在字符串开始的双引号后面或者结束的双引号前面有一个或者多个#,而且能够在结束定界符前包含任何字符序列。
nil类型,写作(),有惟一值。
Rust 的操做符包括基本上没有什么特别的地方。算数运算符有*
、/
、%
、+
和-
(乘、除、取余、加、和减),-
也是一个一员前置运算符,表示负数。和C 同样,也支持位运算符>>
, <<
、&
、|
、和^
。
注意,若是应用于一个整数值,!反转全部的位(像~ 在C 中的做用同样)。
比较操做符有传统的==
、!=
、<
、>
、<=
和>=
。短路(惰性)布尔操做符被写做&&(与)和||(或)。
对于编译时的类型转化,Rust使用二元操做符as
。将表达式放在左侧,并将须要转化的类型放在右边,若是转换有意义,就将表达式的结果转换为给定的类型。一般,as
只能用于原始的整数类型或者指针,而且不能重载。transmute
能够对一样大小和对齐的类型进行转换。
let x: f64 = 4.0; let y: uint = x as uint; assert!(y == 4u);
Rust可让你本身扩展语言没有内建的功能,语法扩展的名字都是以!
结尾的。标准库定义了一些语法扩展,其中,最有用的是 format!
,sprintf-like 的文本格式化程序,以及相关的宏家族 print!
, println!
和 write!
。
format!
借鉴了Python的语法,但包含了许多的printf规则。和printf不一样的是,format!
当类型与参数不匹配的时候会返回编译时的错误。
// `{}` 会打印类型的默认格式 println!("{} is {}", "the answer", 43); // `{:?}` 能够用于任何类型 println!("what is this thing: {:?}", mystery_object);
你可使用宏系统定义本身的语法扩展。更多的细节,macro tutorial,注意:宏特性尚未稳定下来,慎用。
条件语句
if/else
代码例子, 大括号是必须的:
if false { println!("that's odd"); } else if true { println!("right"); } else { println!("neither true nor false"); }
if
后边的条件必须是bool
类型,没有隐式的类型转换,若是if
语句后面的代码块有返回值,返回值的类型必须是同样的。
fn signum(x: int) -> int { if x < 0 { -1 } else if x > 0 { 1 } else { 0 } }
Rust的match
结构比C的switch
更通用,易读。
代码:
match my_number { 0 => println!("zero"), 1 | 2 => println!("one or two"), 3..10 => println!("three to ten"), _ => println!("something else") }
与c的规则相反,Rust语言的match不须要用break明确的退出一个case,只有一个case会执行。
规则:
|
匹配多个值M..N
匹配范围_
会匹配任何值match
必需要有可以匹配到的值,若是传入的值,不会匹配到任何case,编译不会经过=>
后边也支持块表达式( block expression), 这种状况每一个case后边的逗号是可选的。match my_number { 0 => { println!("zero") } _ => { println!("something else") } }
模式匹配颇有用的一个功能是解构(destructuring):
use std::f64; use std::num::atan; fn angle(vector: (f64, f64)) -> f64 { let pi = f64::consts::PI; match vector { (0.0, y) if y < 0.0 => 1.5 * pi, (0.0, _) => 0.5 * pi, (x, y) => atan(y / x) } }
(f64, f64) 是一个元组,会做为match的匹配值,每一个case的时候,vector会被解构,如 (0.0, y)表示匹配vector中,x是0.0的值,而且会把vector中y的值绑定到(0.0,y)中的y。(x, y) 会匹配任何两个元素的元组,元组的值会绑定到x,y 。 而(0.0,_) 第二个元素值会被丢弃。match
的pattern guard
中能够在case写 if EXPR
, angle函数中的第一个case就是,只有if 后的表达式为true的时候,case才被执行。 可使用
variable @ pattern`将匹配到的值赋给变量,例如:
match age { a @ 0..20 => println!("{} years old", a), _ => println!("older than 21") }
let
也支持模式匹配,好比:
let (a, b) = get_tuple_of_two_ints();
while
表示当给定的条件是true
是,会一直循环迭代。关键字break
跳出循环,continue
跳出当前迭代,进行下一次迭代。
let mut cake_amount = 8; while cake_amount > 0 { cake_amount -= 1; }
loop
表示无限循环,是while true
更好的方式:
let mut x = 5u; loop { x += x - 3; if x % 5 == 0 { break; } println!("{}", x); }
官方tutorial: http://static.rust-lang.org/doc/master/tutorial.html