3.基本语法

来源:互联网 发布:淘宝客推广效果如何 编辑:程序博客网 时间:2024/06/06 04:15

假设你已经有任何的C家族语言(C++、Java、JavaScript、PHP或C#)编程经验,你会对Rust感到熟悉。代码被组织在以花括号描述的块中;也有分支和循环的控制结构,类似熟悉的if和while;函数调用类似myfunc(arg1, arg2);操作数也是相同的,且大多数与C语言有相同的优先级;注释也类似C;模块名被双冒号(::)分隔,就像C++。

         表面上的主要不同点是像if和while这样控制结构首部的条件式不需要圆括号,但它们的主体部分必须被花括号封装。单语句、无花括号主体是不被允许的。

fn main() {/* A simple loop */loop {// A tricky calculationif universe::recalibrate() {return;}}}

let关键字标识一个局部变量。变量默认是不可变的。为了声明一个你随后能够再次赋值的局部变量,使用let mut代替let。

let hi = "hi";let mut count = 0;while count < 10 {println!("count is {}", count);count += 1;}

尽管Rust几乎总是能够推测局部变量的类型,但你能够通过在let声明后使用冒号,再加上类型名来指定变量类型。另一方面,常量总是需要一个类型注解。

static MONSTER_FACTOR: f64 = 57.8;let monster_size = MONSTER_FACTOR * 10.0;let monster_size: int = 50;

局部变量可能隐藏更早些的声明,像前面的例子:monster_size首先被声明为f64类型,随后第二个monster_size被声明为int类型。如果你确实编译了这个例子,编译器将认为第一个monster_size没有被使用而发出警告(因为这个情景就像是个程序员错误)。在有意声明未使用变量的场合,它们的名字可能会被冠以下划线的前缀来消除警告信息,就像let _monster_size = 50;

    Rust标识符以字母或下划线开头,其后可跟任意的字母、数字或下划线序列。更好地编程风格是写函数、变量和模块名时使用小写字母,使用下划线帮助阅读,在自定义类型时使用驼峰式大小写。

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这个名称:

let price =if item == "salad" {3.50} else if item == "muffin" {2.25} else {2.00};

上述代码是等价的:它们赋值给price取决于持有的条件。注意在第二个代码段的块中没有分号。这是重要的:花括号中的最后一条语句缺省分号使得最后表达式的值成为整个代码块的值。

         换句话说,Rust中的分号忽略了表达式的值。因此,如果一个if分支有类似{ 4; }的样子,上述例子将简单的赋值()(unit或void)给price。但没有分号,每个分支有不同的值,price获得被选定分支的值。

         简短地说,所有的一切不是声明(let声明变量;fn声明函数;任何顶层的命名项目,像traits、enum类型和常量)就是表达式,包括函数主体。

fn is_four(x: int) -> bool {// No need for a return statement. The result of the expression// is used as the return value.x == 4}

基本数据类型与字面值

         基本数据类型有常见的有符号无符号的整型int和uint,也有8-,16-,32-和64-位的变量i8,u16等。整型能够写成十进制(144)、十六进制(0x90)、八进制(0o70)或者二进制(0b1001000)。每个整数类型都有一个相关联的能够预示类型的字面后缀:i表示int,u表示uint,i8表示i8类型。

         当缺省整数字面后缀时,Rust将根据程序周围的类型注解和函数特征推测数据类型。当缺省所有的类型信息时,Rust假定无后缀整数字面值类型为int。

let a = 1; // `a` is an `int`let b = 10i; // `b` is an `int`, due to the `i` suffixlet c = 100u; // `c` is a `uint`let d = 1000i32; // `d` is an `i32`

基本数据类型也有两个浮点类型:f32和f64。浮点数可以写成0.0、1e6或者2.1e-4的形式。和整型一样,浮点字面值通过推测获得正确的类型。后缀f32和f64能被用来创建类型明确的字面值。

        关键字true和false引出bool类型的字面值。

        字符,即char类型,是4字节的Unicode编码,它的字面值写在单引号间,如‘x’。就像C一样,Rust能够识别一些使用反斜杠的转义字符,如\n、\r和\t。字符串字面值写在双括号间,不像PHP或shell,它允许不作任何处理使用相同的转义序列。

        另一方面,原始的字符串字面值不处理任何的转义序列。它们被写做r##”blah”##,在左引号前和右引号后匹配零个或多个#,而且能够包含除结束分隔符外的任意字符序列。更多的字符串随后介绍。

        unit类型写做(),有唯一值,也写做()。

操作符

         Rust的操作符有很少的惊喜。算术运算使用*、/、%、+、-(乘、除、取余、加、减)。-也是相反数的一元操作符前缀。像C中的位运算符<<、>>、&、|和^也被支持。

         注意,如果对整数值使用!,表示反转所有的位(按位取反,就像C中的~)。

         比较操作符是传统的==、!=、>、<、>=和<=。短路求值布尔操作符写做&&(and)和||(or)。

         对于编译时类型转换,Rust使用二元操作符as。操作符左边为表达式,右边为类型。如果一个有意义的转换存在,表达式的类型将被转换成给定的类型。通常,as仅仅用在基本数字类型或者指针,且不可被重载。transmute能够被用来作为类似C的非安全的相同大小的类型转换。

let x: f64 = 4.0;let y: uint = x as uint;assert!(y == 4u);

语法扩展

         语法扩展是非语言内建的特殊形式,而是被以库的方式提供。为了让读者更清晰地意识到某个名字是语法扩展,所有语法扩展的名字都以!结束。标准库定义了一些语法扩展,最有用的是format!,一个你经常在例子里见到的类似sprintf的文本格式化程序。和它相关的宏系列有:print!、println!和write!。

         format!的语法来自Python,但包含许多printf拥有的原则。不像printf,当指令类型不匹配参数类型时,format!将给你一个编译时错误。

// `{}` will print the "default format" of a typeprintln!("{} is {}", "the answer", 43);// `{:?}` will conveniently print any typeprintln!("what is this thing: {:?}", mystery_object);

通过宏系统,你能够定义自己的语法扩展。细节请参考宏指南。注意,当前宏定义被考虑为不稳定特征。


0 0
原创粉丝点击