🖐🏻 免责声明
本教程仅供学习交流使用,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,请各读者自觉遵守相关法律法规。
本教程不针对无基础者,默认至少熟悉一门其他编程语言,主要讲解一些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);
}
}
- 整型
- :u8 用冒号指定类型
- 12u8 数字后加类型
- 0xAA 16进制写法,hex字符串表达方式
- 1000_000 多位置,用_可以被识别
- as u8 用as进行类型强转
- 布尔
- 字符串
- :String 大写S为类型
- utf8(b"") 固定这写法就行
- 地址
- @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}
}
上述代码会报错,解决方案有两个
struct Foo has drop{}drop能力可以在函数结束后将对象丢弃,就不会报错了,你就理解为垃圾回收吧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
在前面函数修饰符讲过了
更多内容等我学到了再来分享哈

