move基础语法

🖐🏻 免责声明

本教程仅供学习交流使用,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,请各读者自觉遵守相关法律法规。

本教程不针对无基础者,默认至少熟悉一门其他编程语言,主要讲解一些move与众不同的特性

# 所有权转移

let people = {"age":25,name:"motuoka"}
let people2 = people
people2.age = 30
console.log(people.age) //30
console.log(people2.age) //30

上面代码是js,很好理解,但在move中,let people2 = people这一步将people所有权就转给people2了,people变量等于没了,不能再用了

# 基础类型

直接上代码

#[test_only]
module 0x33::main {
    use std::debug::print;
    use std::string::{utf8,String};

    #[test]
    fun testInt(){
        let a:u8 = 10;
        let b = 31u8;
        let c:u8 = 0x0A;
        print(&a);
        print(&b);
        print(&c);

        let d:u256 = 1000_000;
        print(&d);

        let e:u256 = (c as u256)+d;
        print(&e)
    }

    #[test]
    fun test_bool(){
        let a:bool = true;
        let b:bool = false;
        print(&a);
        print(&b);
        let c = 1 < 2;
        print(&c);
    }

    #[test]
    fun test_string(){
        let a:String = utf8(b"hello world");
        print(&a);
    }

    #[test]
    fun test_addr(){
        let addr:address = @0x6a;
        let addr1:address = @0x36a1acd6a99d393e4a71778a7a66fc51fb903fab06acebe082a2334f0f79eaff;
        print(&addr);
        print(&addr1);
    }
}

  1. 整型
    • :u8 用冒号指定类型
    • 12u8 数字后加类型
    • 0xAA 16进制写法,hex字符串表达方式
    • 1000_000 多位置,用_可以被识别
    • as u8 用as进行类型强转
  2. 布尔
  3. 字符串
    • :String 大写S为类型
    • utf8(b"") 固定这写法就行
  4. 地址
    • @0xa6 @加开头,0x hex字符串

# Vector数组

# 查询数组

直接上代码,功能用一行注释代替,如果复制代码去执行,记得把中文注释先拿掉

#[test_only]
module 0x33::vector_demo{
    use std::debug;
    use std::vector;
    use aptos_std::debug::print;

    const ARR:vector<u64> = vector[1, 2, 3, 4, 5,6,7,8,9,10];

    #[test]
    fun test_vector(){
        debug::print(&ARR);
    }

    #[test]
    fun test_vector_empty(){
//        数组是否为空
        let b = vector::is_empty(&ARR);
        debug::print(&b);
    }

    #[test]
    fun test_vector_length(){
//        数组长度
        let b = vector::length(&ARR);
        debug::print(&b);
    }

    #[test]
    fun test_vector_borrow(){
//        获取数组的第3个元素,不可变
        let b = vector::borrow(&ARR, 3);
        debug::print(b);
    }

    #[test]
    fun test_vector_borrow_mut(){
        // 获取数组的第5个元素,可变,并改变第五个元素的值
        let arr = vector[1, 2, 3, 4, 5,6,7,8,9,10];
        let b = vector::borrow_mut(&mut arr, 5);
        *b = 120;
        debug::print(&arr);

    }

    #[test]
    fun test_vector_contains(){
        // 查找数组中是否存在某个元素,返回一个bool类型
        let n = 1;
        let n2 = 30;
        let b = vector::contains(&ARR, &n);
        print(&b);

        let c = vector::contains(&ARR, &n2);
        print(&c);
    }

    #[test]
    fun test_vector_indexof(){
        // 查找数组中某个元素的索引,返回一个元组,第一位是bool代表是否存在;第二位是索引
        let n = 2;
        let (b,c) = vector::index_of(&ARR, &n);
        print(&b);
        print(&c);


        let n2 = 122;
        let (b2,c2) = vector::index_of(&ARR, &n2);
        print(&b2);
        print(&c2);
    }
}

# 增删改数组

直接上代码,功能用一行注释代替,如果复制代码去执行,记得把中文注释先拿掉

#[test_only]
module 0x33::vector_edit{
    use std::vector;
    use std::debug;
    #[test]
    fun test_vector_push(){
	    //最后插入一条数据
        let arr = vector[1, 2, 3, 4, 5,6,7,8,9,10];
        vector::push_back(&mut arr, 5);
        debug::print(&arr);
    }


    #[test]
    fun test_vector_pop(){
		//删除最后一条数据,并且返回这条数据
        let arr = vector[1, 2, 3, 4, 5,6,7,8,9,10];
        let a = vector::pop_back(&mut arr);
        debug::print(&arr);
        debug::print(&a);
    }

    #[test]
    fun test_vector_destroy(){
	//删除空数组
        let arr = vector[1];
        vector::remove(&mut arr,0);
        vector::destroy_empty(arr);
        // debug::print(&arr);
    }

    #[test]
    fun test_vector_append(){
	//拼接两个数组
        let arr = vector[1, 2, 3, 4, 5,6,7,8,9,10];
        let arr2 = vector[678, 900, 1000];
        vector::append(&mut arr, arr2);
        debug::print(&arr);
    }

    #[test]
    fun test_vector_reverse_append(){
	//将第二个数组反向排序后拼接到第一个数组后面
        let arr = vector[1, 2, 3, 4, 5,6,7,8,9,10];
        let arr2 = vector[678, 900, 1000];
        vector::reverse_append(&mut arr, arr2);
        debug::print(&arr);
    }

    #[test]
    fun test_vendor_swap(){
    //交换第0位和第一位的数据
        let arr = vector[1, 2, 3, 4, 5,6,7,8,9,10];
        vector::swap(&mut arr, 0, 1);
        debug::print(&arr);
    }

    #[test]
    fun test_vendor_reverse(){
    //将数组倒序
        let arr = vector[1, 2, 3, 4, 5,6,7,8,9,10];
        vector::reverse(&mut arr);
        debug::print(&arr);
    }

    #[test]
    fun test_vendor_reverse_slice(){
    //将第二位到第六位(不含)之间的元素倒序
        let arr = vector[1, 2, 3, 4, 5,6,7,8,9,10];
        vector::reverse_slice(&mut arr,2,6);
        debug::print(&arr);
    }

    #[test]
    fun test_vendor_insert(){
    //在第二位的位置插入一个100
        let arr = vector[1, 2, 3, 4, 5,6,7,8,9,10];
        vector::insert(&mut arr, 2, 100);
        debug::print(&arr);
    }

    #[test]
    fun test_vendor_remove(){
    //将第二位的元素删除
        let arr = vector[1, 2, 3, 4, 5,6,7,8,9,10];
        vector::remove(&mut arr,2);
        debug::print(&arr);
    }

    #[test]
    fun test_vector_swap_remove(){
    //将第二位和最后一位交换位置,并将原来第二位的元素删除,并返回这个值
        let arr = vector[1, 2, 3, 4, 5,6,7,8,9,10];
        let a = vector::swap_remove(&mut arr,2);
        debug::print(&arr);
        debug::print(&a);
    }

    #[test]
    fun test_vendor_trim(){
    //将数组缩短为5位,并返回被裁掉的那段数组
        let arr = vector[1, 2, 3, 4, 5,6,7,8,9,10];
        let a = vector::trim(&mut arr,5);
        debug::print(&arr);
        debug::print(&a);
    }

    #[test]
    fun test_vendor_trim_reverse(){
    //将数组缩短为5位,并返回被裁掉的那段数组的倒序体
        let arr = vector[1, 2, 3, 4, 5,6,7,8,9,10];
        let a = vector::trim_reverse(&mut arr,5);
        debug::print(&arr);
        debug::print(&a);
    }

    #[test]
    fun test_vendor_rotate(){
    //将第三位开始往后的元素整个换到数组最前面,并返回新数组第三位的元素
        let arr = vector[1, 2, 3, 4, 5,6,7,8,9,10];
        let a = vector::rotate(&mut arr,3);
        debug::print(&arr);
        debug::print(&a);
    }

    #[test]
    fun test_vendor_rotate_slice(){
    //将3-8位的元素进行变换,这里就是45678,12和9 10位置暂时不变,然后从原数组的第五位开始到第八位,即678和3-5位,即45,位置变换,最终结果为123678459 10,并返回开始变换的位置的新数据,位置是第3位,新数据就是6
        let arr = vector[1, 2, 3, 4, 5,6,7,8,9,10];
        let a = vector::rotate_slice(&mut arr,3,5,8);
        debug::print(&arr);
        debug::print(&a);
    }
}

# 函数修饰符

# 可见性及链下

  • 无public
  • public
  • public(friend)
  • public entry fun :entry 供链下引用
address 0x42{
    #[test_only]
    module a{
        friend 0x42::b;
        #[test]
        fun fun1(){
            std::debug::print(&1);
        }
        #[test]
        public fun fun2(){
            std::debug::print(&2);
        }
        #[test]
        public(friend) fun fun3(){
            std::debug::print(&3);
        }
    }

    module b{

        // #[test]
        // fun fun4(){
        //     // error这个方法不正确,无法调用另外的模块不含public的方法
        //     0x42::a::fun1();
        // }
        #[test]
        fun fun5(){
            //有 public可以调用
            0x42::a::fun2();
        }
        #[test]
        fun fun6(){
            // need friend on module a,想调用friend的方法,需要成为那个模块的friend模块,在a模块上面写下friend 0x42::b;
            0x42::a::fun3();
        }
    }
}

# 全局存储引用

acquires,当需要使用以下方法

  • move_from
  • borrow_global
  • borrow_global_mut

需要在函数后加上acquires struct名

#[test_only]
module 0x77::lesson6_1{
    use std::acl::add;
    use std::debug::print;
    use std::signer;

    struct Coin has key{
        value: u64
    }

    public entry fun mint(account:&signer, value:u64){
        let coin = Coin{value};
        move_to(account,coin);
    }

    #[test(account=@0x77)]
    fun testmint(account:&signer) acquires Coin {
        let addr = signer::address_of(account);
        mint(account,20);
        let coin = borrow_global<Coin>(addr).value;
        print(&coin);
    }
}

# Struct能力

# Drop

struct Foo {
	a:u8
}
fun main(){
    let foo = Foo{a:1}
}

上述代码会报错,解决方案有两个

  1. struct Foo has drop{}drop能力可以在函数结束后将对象丢弃,就不会报错了,你就理解为垃圾回收吧
  2. let Foo{a,b}=foo进行解构赋值,这样也不会再报错

# Copy

我们第一节提到的move具有所有权转移,搞得它和别的语言比起来有点别扭,copy能力就解决了这个问题

struct Foo has drop,copy{
	a:u8
}
fun main(){
    let m = CanCopy{a:1};
    let n = copy m;//这里copy可加可不加
    let CanCopy{a} = &mut n;
    *a = 5;
    print(&m.a);//1
    print(&n.a);//5
}

# Key & Store

简单来讲,Key可以把值全局存到账户地址下,可以通过borrow_global等方法访问到,Store配合Key使用,若被嵌套在拥有Key能力的Struct下的子Struct,必须拥有Store的能力,不然会报错

struct Key has key,drop{
        a:Store
    }

    struct Store has store,drop{
        b:u8
    }

    #[test]
    fun main4(){
        let k = Key{a:Store{b:1}};
        let Key{a} = k;
        let Store{b} = a;
        print(&b);
    }

# 函数控制流

这里和其他语言区别不大,有if,while,loop,其中loop是无限循环,continue跳过本次循环,break中断循环。

老规矩,来段代码助助兴,需要注意break和continue时,分号的特殊位置

if (a == 3) {
    continue
};
#[test_only]
module 0x88::main{
    use std::debug::print;
    use std::string::{utf8};

    #[test]
    fun test_if(){
        let x = 5;
        if (x == 5) {
            print(&utf8(b"x is 5"));
        }else {
            print(&utf8(b"x is not 5"));
        }
    }

    #[test]
    fun test_while(){
        let a = 5;
        while(a > 0){
            a = a - 1;
            print(&a);
            if (a == 3) {
                continue
            };
            // if (a == 3) {
            //     break
            // };
        }
    }

    #[test]
    fun test_loop(){
        let a = 10;
        loop {
            a = a - 1;
            print(&a);
            if (a == 3) {
                break
            };
        }
    }
}

# 模块

# 引用

use std::debug::print;
use std::debug;
use std::debug::{print as P1}
use std::string::{utf8,String}

# 作用域

fun main(){
	use std::debug::print;
	let a = 8;
	print(&8);
}

# friend

在前面函数修饰符讲过了


更多内容等我学到了再来分享哈

# ☕ 请我喝咖啡

如果本文章对您有所帮助,不妨请作者我喝杯咖啡 :)

pay


# ☀️ 广告时间

现承接以下业务,欢迎大家支持:)

  • Web 2.0 & Web 3.0应用定制
  • Web 3.0专项脚本定制与优化
  • 数据爬虫需求快速响应
  • 网站/公众号/小程序一站式开发
  • 毕业设计与科研项目支持
  • 企业管理软件定制:ERP, MES, CRM, 进销存系统等

联系方式:

X:@motuoka

V:ck742931485

wx