语法基础

注释

行注释

let x = 5  // 绑定

块注释
出于某种原因,Rust中不太建议使用。但其实无所谓。

/*
    let x = 42;
    println!("{}", x);
*/

文档注释
使用 /// 。用于函数或结构体(字段)的说明,置于要说明的对象上方。文档注释内部可使用markdown格式的标记语法。 类似于javadoc,可以用rustdoc命令提取代码内的注释。

/// 输入一个数字。
/// 返回该数字加1后的值。
fn add_one(x: i32) -> i32 {
    x + 1
}

模块注释 使用 //! ,用于说明当前模块的功能。置于模块文件的头部。

//! # 自定义Rust HTTP库。
//!
//! 该模块提供了HTTP网络编程相关功能。

语句

Rust使用 ; 作为语句的分隔符,这与Java一样。 另外,Rust是基于表达式的语言,这与Scala一样。即

每段代码块都是有值的。其值等于代码块最后一条语句的值。

例:rust中没有三目运算符(?:) ,因为不需要,直接这样这样使用。

let y = if x == 5 { 10 } else { 15 };

绑定初步

变量绑定是Rust中最复杂且最重要的概念。这里先做简单学习,后续深入。

// 变量绑定
let a1 = 5;
let a2:i32 = 5;

a1 = 10;   // 不可变变量无法再赋值,该语句无法通过编译。

// 可变绑定
let mut b1 = 5;
b1 = 10;
  • 使用let的变量,变量不可变。变量不可再次被“赋值”。
  • 使用let mut的变量,变量可变。可以再次被“赋值”。

与Java的final不同,Rust中的不可变变量是指资源的不可变。

例:

let a = vec![1,2,3];    // vec![1,2,3]是不可变的。已经固定的值。
a.push(4);    // 编译报错。
println!("{:?}", a);

必须要使用let mut才可以对值做操作。

let mut a = vec![1,2,3];
a.push(4);
println!("{:?}", a);    // 输出 [1, 2, 3, 4]

“不可变变量” 与“可变变量”的转换

let a = 5;
let mut b = a;  // 不可变 -> 可变
b += 10;
println!("{:?},{:?}", a,b);  // 输出5,15

let mut c = 10;
c += 10;
let d = c;  // 不可变 -> 可变
println!("{:?},{:?}", c,d);  // 输出20,20

多值“赋值”

类似Go语言的多值赋值。

// 不需要声明变量类型
let (a1,a2,a3) = (10,20,30);
println!("{:?},{:?},{:?}", a1,a2,a3);

// 声明变量类型
let (b1,b2,b3) : (bool,i32,bool)= (true,32,false);
println!("{:?},{:?},{:?}", b1,b2,b3);

// 混合let与let mut的变量绑定
let (c1,mut c2,c3) : (bool,i32,bool)= (true,32,false);
c2 += 10;
println!("{:?},{:?},{:?}", c1,c2,c3);

const 常量

Rust的const不是真正的变量。因为该常量变量不存在于内存中。而是在编译阶段直接嵌入了代码中。

const PI:f32 = 3.14;

基础类型

类型 说明
布尔 true或false
字符 let c = 'c'; 单Unicode字符,1个字符4个字节
有符号整数 let x = 42; 所有的符号整数 (i8, i16, i32, i64, isize)
无符号整数 let x:u8 = 255; 无符号整数 (u8, u16, u32, u64, usize)
浮点数 let x:f64 = 1.23e+2; 浮点数 (f32, f64)
字符串 let str = "Hello, world!";
let mut string = str.to_string();
最底层的是不定长类型str,更常用的是字符串切片&str和堆分配字符串String, 其中字符串切片是静态分配的,有固定的大小,并且不可变,而堆分配字符串是可变的。
数组 let a = [0, 1, 2, 3, 4];
let mut ten_zeros: [i64; 10] = [0; 10];
具有固定大小,并且元素都是同种类型,可表示为[T; N]。
切片 let a = [0, 1, 2, 3, 4];
let middle = &a[1..4];
引用一个数组的部分数据并且不需要拷贝,可表示为&[T]。
元组 let tuple: (i32, &str) = (50, "hello");
let (fifty, _) = tuple;
let hello = tuple.1;
具有固定大小的有序列表,每个元素都有自己的类型,通过解构或者索引来获得每个元素的值。
指针 let x = 5;
let raw = &x as const i32;
let points_at = unsafe {
raw };
最底层的是裸指针const T和mut T,但解引用它们是不安全的,必须放到unsafe块里。
函数 fn foo(x: i32) -> i32 { x }
let bar: fn(i32) -> i32 = foo;
具有函数类型的变量实质上是一个函数指针。
元类型 () 其唯一的值也是()。

对于数值

数值类型可以使用_分隔符来增加可读性。

对于字符

Rust还支持单字节字符b'H'以及单字节字符串b"Hello",仅限制于ASCII字符。 此外,还可以使用r#"..."#标记来表示原始字符串,不需要对特殊字符进行转义。

对于字符串

使用&符号将String类型转换成&str类型很廉价, 但是使用to_string()方法将&str转换到* String类型涉及到分配内存, 除非很有必要否则不要这么做。

对于数组

数组的长度是不可变的,动态的数组称为Vec (vector),可以使用宏vec!创建。

对于元组

元组可以使用==和!=运算符来判断是否相同。 不多于32个元素的数组和不多于12个元素的元组在值传递时是自动复制的。

类型转换

Rust不提供原生类型之间的隐式转换,只能使用as关键字显式转换。

别名

可以使用type关键字定义某个类型的别名,并且应该采用驼峰命名法。

results matching ""

    No results matching ""