上一篇文章我们已经介绍了Move开发的环境配置以及Move内置的基本类型u8,u64,u128,boolean以及address,我们还了解了Move与其他的智能合约开发语言不同,Move将脚本与模块区分开,脚本中包含更多的逻辑,这篇文章将会主要介绍Move的表达式与作用域,以及控制流。
在编程语言中,表达式是指拥有返回值的代码单元,例如一个有返回值的函数调用就是表达式。
❝表达式必须要用分号分隔
❞
在move中一个空括号代表一个空表达式,空表达式会被虚拟机自动忽略,以下就是一个空表达式的例子:
script {
fun empty() {
() //这是一个空表达式
}
}
看下面的代码,每一行以分号结尾都是一个表达式。
script {
fun main() {
10;
10 + 5;
true;
true != false;
0x1;
1; 2; 3
}
}
这些都是最简单的表达式,那么为什么我们需要它们?我们又该如何利用它们呢?不知道还记不记得上一篇文章我们介绍基本数据类型时定义基本类型的变量,这就是对于表达式的运用,通过let关键字声明变量,然后将表达式的值存储在变量中:
script {
fun main() {
let a;
let b = true;
let c = 10;
let d = 0x12;
a = c
}
}
Move中提供了很多整型的运算符可以改变整型的值
运算符 | 含义 |
---|---|
+ | 相加 |
- | 相减 |
/ | 除 |
* | 乘 |
% | 除余 |
<< | 左移 |
>> | 右移 |
& | 与 |
^ | 异或 |
| | 或 |
在Move语言中每一个变量都必须被使用,否则代码无法编译通过,以下代码编译会报错
script {
fun main() {
let a = 1;
}
}
其报错如下
warning[W09003]: unused assignment
┌─ ./sources/test.move:3:12
│
3 │ let a = 1;
│ ^ Unused assignment or binding for local 'a'. Consider removing, replacing with '_', or prefixing with '_' (e.g., '_a')
报错提示也说了可以通下划线"_"代替a,以下代码就不会报错
script {
fun main() {
let _ = 1;
}
}
在Move中允许定义一个变量两次,但是必须使用"_"将第一次定义的值标记为不使用,其代码如下:
script {
fun main() {
let a = 1;
let a = 2;
let _ = a;
}
}
一个由{}包围组成的代码块也是一个表达式,一个代码块可以包含表达式,也可以包含其他代码块,从某种意义上说函数体也是带有某种限制的代码块。
script {
fun block() {
{ };
{ { }; };
true;
{
true;
{ 10; };
};
{ { { 10; }; }; };
}
}
在Move中作用域就是由{}所包围的代码块,代码块可以相互嵌套且没有限制。
script {
fun main() {
//这是一个函数体
{
//这是函数体内的一个代码块
{
//这是代码块中的一个代码块
};
};
{
//函数体内的另一个代码块
};
}
}
对于变量而言,代码块内部可以访问外部的变量,但是外部却无法访问代码块内部的变量
script {
fun main() {
let a = 2;
{
let b = a + 2;
};
let c = b + 3;
}
}
代码块也是一个表达式,一个表达式就有返回值,其返回值就是最后一个没有分号的表达式的值
script {
fun main() {
let a = {
let c = 10;
c * 100
};
let _ = a;
}
}
Move与其他语言相同,也有控制流语句,主要是循环的while和loop,以及if。
Move语言的if与其他语言的使用并无什么特别大的差异。
script {
fun main() {
let a = true;
let b = if (a) {
10
} else {
20
};
}
Move 语言中While的使用也与其他语言相同
script {
fun main() {
let i = 0;
while(i < 5) {
i = i + 1;
};
}
与其他语言不同,Move提供了一个无条件的循环loop,没有终止条件,不加干预会一直循环下去
script {
fun main() {
let i = 0;
loop {
i = i + 1;
};
// UNREACHABLE CODE
let _ = i;
}
}
为了能够终止循环,Move提供来break和continue,其用法与其他语言相同
script {
fun main() {
let i = 0;
loop {
i = i + 1;
if (i / 2 == 0) continue;
if (i == 5) break;
// assume we do something here
};
0x1::Debug::print(&i);
}
}
有时候一些条件触发,需要废弃函数执行,这也是智能合约常用的场景,Move提供了abort关键字。
script {
fun main(a: u8) {
if (a != 10) {
abort 0;
}
//如果a不等于10程序不会执行到这里
}
}
assert是对abort的进一步包装
script {
fun main(a: u8) {
assert!(a == 10, 0);
//如果a等于10程序会执行到这里
}
}
这篇文章主要介绍了Move的表达式与控制流,更多文章可以关注公众号QStack。