• 下一代智能合约编程语言Move(二)


    前言

    上一篇文章我们已经介绍了Move开发的环境配置以及Move内置的基本类型u8,u64,u128,boolean以及address,我们还了解了Move与其他的智能合约开发语言不同,Move将脚本与模块区分开,脚本中包含更多的逻辑,这篇文章将会主要介绍Move的表达式与作用域,以及控制流。

    表达式与作用域

    在编程语言中,表达式是指拥有返回值的代码单元,例如一个有返回值的函数调用就是表达式。

    表达式必须要用分号分隔

    空表达式

    在move中一个空括号代表一个空表达式,空表达式会被虚拟机自动忽略,以下就是一个空表达式的例子:

    script {
        fun empty() {
            () //这是一个空表达式
        }
    }
    • 1
    文字表达式

    看下面的代码,每一行以分号结尾都是一个表达式。

    script {
        fun main() {
            10;
            10 + 5;
            true;
            true != false;
            0x1;
            1; 2; 3
        }
    }

    • 1

    这些都是最简单的表达式,那么为什么我们需要它们?我们又该如何利用它们呢?不知道还记不记得上一篇文章我们介绍基本数据类型时定义基本类型的变量,这就是对于表达式的运用,通过let关键字声明变量,然后将表达式的值存储在变量中:

    script {
        fun main() {
            let a;
            let b = true;
            let c = 10;
            let d = 0x12;
            a = c
        }
    }
    • 1
    整型的运算符

    Move中提供了很多整型的运算符可以改变整型的值

    运算符含义
    +相加
    -相减
    /
    *
    %除余
    <<左移
    >>右移
    &
    ^异或
    |
    "_"与标记未使用

    在Move语言中每一个变量都必须被使用,否则代码无法编译通过,以下代码编译会报错

    script {
        fun main() {
           let a = 1;
        }
    }
    • 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')
    • 1

    报错提示也说了可以通下划线"_"代替a,以下代码就不会报错

    script {
        fun main() {
           let _ = 1;
        }
    }
    • 1

    在Move中允许定义一个变量两次,但是必须使用"_"将第一次定义的值标记为不使用,其代码如下:

    script {
        fun main() {
           let a = 1;
           let a = 2;
           let _ = a;
        }
    }
    • 1
    块表达式

    一个由{}包围组成的代码块也是一个表达式,一个代码块可以包含表达式,也可以包含其他代码块,从某种意义上说函数体也是带有某种限制的代码块。

    script {
        fun block() {
            { };
            { { }; };
            true;
            {
                true;

                { 10; };
            };
            { { { 10; }; }; };
        }
    }
    • 1
    理解作用域

    在Move中作用域就是由{}所包围的代码块,代码块可以相互嵌套且没有限制。

    script {
        fun main() {
            //这是一个函数体
          {
            //这是函数体内的一个代码块
            {
                //这是代码块中的一个代码块
            };
          };
          {
            //函数体内的另一个代码块
          };
        }
    }
    • 1
    变量的生命周期

    对于变量而言,代码块内部可以访问外部的变量,但是外部却无法访问代码块内部的变量

    script {
        fun main() {
            let a = 2;
          {
            let b = a + 2;  
          };
          let c = b + 3;
        }
    }
    • 1
    代码块的返回值

    代码块也是一个表达式,一个表达式就有返回值,其返回值就是最后一个没有分号的表达式的值

    script {
        fun main() {
          let a = {
            let c = 10;
            c * 100
          };
          let _ = a;
        }
    }
    • 1

    控制流

    Move与其他语言相同,也有控制流语句,主要是循环的while和loop,以及if。

    if

    Move语言的if与其他语言的使用并无什么特别大的差异。

    script {
        fun main() {
          let a = true;
          let b = if (a) {
            10
            } else {
                20 
                };
    }
    • 1
    while

    Move 语言中While的使用也与其他语言相同

    script {
        fun main() {
          let i = 0;

          while(i < 5) {
            i = i + 1;
          };
    }
    • 1
    无条件循环loop与break,continue

    与其他语言不同,Move提供了一个无条件的循环loop,没有终止条件,不加干预会一直循环下去

    script {
        fun main() {
            let i = 0;

            loop {
                i = i + 1;
            };

            // UNREACHABLE CODE
            let _ = i;
        }
    }
    • 1

    为了能够终止循环,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);
        }
    }
    • 1
    abort

    有时候一些条件触发,需要废弃函数执行,这也是智能合约常用的场景,Move提供了abort关键字。

    script {
        fun main(a: u8) {

            if (a != 10) {
                abort 0;
            }
            //如果a不等于10程序不会执行到这里
        }
    }
    • 1
    assert

    assert是对abort的进一步包装

    script {

        fun main(a: u8) {
            assert!(a == 10, 0);

           //如果a等于10程序会执行到这里
        }
    }

    • 1

    最后

    这篇文章主要介绍了Move的表达式与控制流,更多文章可以关注公众号QStack。

  • 相关阅读:
    第14章 操作重载与类型转换【C++】
    layer弹出框详细说明
    java计算机毕业设计计算机类课程实验平台源码+数据库+系统+lw文档+mybatis+运行部署
    坚持写作是一个很难的事情
    STM32——HAL库中寄存器地址名称映射分析
    asp.net core 资源过滤器
    GaussDB数据库SQL系列-定义重载函数
    图解OneFlow的学习率调整策略
    快速编写CSDN博客 小技巧
    Golang小数点保留
  • 原文地址:https://blog.csdn.net/QStack/article/details/127760156