RUST语法的骨架
三部分:
属性部分(#![…])
行分隔符号:(;)
块分隔符号:({})
语句和表达式
首先,我门要明确一个概念:
编程中的表达式和语句
- 说到表达式,大多数人想到的可能是数学表达式;程序中的表达式也类似,他是一个由操作符和操作数组成的算术或逻辑运算式,它可以产生一个值。
- 语句是命令式编程语言的一个语法单元,表示程序要执行的操作。程序是有一个或多个语句序列,语句可能包含内部组件。
所以:"表达式"(expression)是一个单纯的运算过程,总是有返回值;
"语句"(statement)是执行某种操作,没有返回值。
广义上每行都是一个语句;
根据每行做的事情的不同,可以把语句分成:
-
声明语句(定义结构体,定义函数,引入模块,赋值)
-
流程控制语句(条件分支,循环,case语句)
-
表达式语句(用于求值)
-
宏语句(文本替换,生成代码)
对应到 RUST中
RUST中的概念
了解为什么RUST是面向表达式的语言?
RUST借鉴了函数式编程语言,函数式编程语言的特点即:
- 面向表达式。通过计算表达式进行求值,而不是修改语句。
函数式编程要求,只使用表达式,不使用语句。
也就是说,每一步都是单纯的运算,而且都有返回值。
在RUST中:
-
RUST中行分隔符(;),块分隔符({})是最基本的表达式。
- 既然是表达式,他就有返回值,这里行分隔符(;表达式) 永远返回自身的单元类型【()】
-
RUST中,行分隔符(;表达式) 只在块表达式最后一样才会求值,其他时候是链接符。
-
RUST中,块表达式只对最后一行表达式进行求值。
看下下面代码加深下对上面几句的理解:
fn main(){
;
;
{
()
}
{
();
use std:vec:Vec; //返回单元值类型()
}
();
&{;};//返回 &()
;
;// 这里返回() 是main的返回值。上面其他的 ;是分隔符
}
这就能理解rust中的隐式返回了
fn main(){
let a = 1;
let b = 2;
a+b //
}
- 首先块表达式只对最后一样进行求值:这里是 a+b 表达式,得到一个值,作为main的 返回值。
- 其次 如果在a+b 后面加上 ;的话,这里最后一个表达式就成了 ; 这时候返回值变成了()
fn plus(i:&u32)->u32{
let i = i+1;
i //这里不加分号,返回的就是块表达值的最后一个表达式(i),如果加了分号,返回的就是单元类型了()
}
RUST中一切皆表达式;
- 除了基本的声明语句之外,其他的基本都属于表达式;
- 字面量是表达式,路径是表达式,流程控制是表达式。
看下例子:
fn main(){
//默认返回单元类型
}
-----
println!() //宏 返回单元类型
-----
fn main(){
for i in 1..102{
if i%15 == 0{println!("fizzbuzz")}
else if i%3==0{println!("fizz")}
else if i%5==0{println!("buzz")}
else{println!("{}",i)}
}
}
//这里 if 返回值是 单元类型。for返回值也是单元类型。和 main 返回类型一致
//使用 match表达式实现:
fn main(){
for i in 1..102 {
match(i%3,i%5){
(0,0)=>println!('fizzbuzz'),
(0,_)=>println!('fizz'),
(_,0)=>println!('buzz'),
(_,_)=>println!("{}",i)
}
}
}
由于 表达式都是 有具体值的,一个具体的值就会有他的类型,所以可以说:RUST一切皆类型。
RUST就是通过对类型进行各种检查实现内存安全和并发安全。
了解rust的求值规则很有必要。