무브 언어에서 가장 생소한 것은 Module
이라는 개념이다. 이 때문에 나는 이번에도 Module에 대해 다룬 문서를 살펴봤다.
모듈은 개발자가 자신의 주소에 함수나 타입들의 한 데 모아놓은 세트이다.
스크립트는 0x1(standard)
주소로 배포된 모듈인 표준 라이브러리와 다른 배포된 모듈들에 명령만 할 수 있다.
모듈을 배포할 때는 그래서, 거기에 포함된 어떤 함수도 실행되지 않는다. 모듈을 사용하기 위해서는 스크립트를 사용해야한다.
모듈은 module
키워드로 시작되는데, 이름과 중괄호가 따라오게 된다. 중괄호 안에는 모듈 컨텐츠가 위치한다.
[module 예시]
module math {
public fun sum(a: u64, b: u64): u64 {
a + b
}
}
기본적으로 모듈은 본인의 계정 주소로 컴파일되어 배포되어진다. 하지만 모듈을 로컬 환경에서 사용하거나 모듈 파일에서 본인의 주소를 특정하고 싶당면 address <addr>
을 사용하면 된다.
[address 명시 예시]
address 0x1 {
module math {
public fun sum(a: u64, b: u64): u64 {
a + b
}
}
}
Move
의 기본 Context는 비어있다. 쓸 수 있는 타입은 원시타입(integers, bool, address) 밖에 없다. 비어있는 Context에서 할 수 있는 거라고는 이 타입과 변수들로 명령을 내리는 것 뿐인데, 의미있는 것을 만들 수는 없다. 이를 위해서 모듈과 표준 라이브러리를 import 해오는 것이다.
use <Address>::<ModuleName>;
Address
는 배포자의 계정 주소이고, ModuleName
은 모듈의 이름이다.
가져온 모듈의 메소드에 접근하기 위해서는 ::
표기를 사용하면 된다.
스크립트에서는 모듈 가져오기를 반드시 중괄호 안에서 작성해야 한다.
[스크립트에서 모듈 가져오기]
script {
use 0x1::Vector;
fun main() {
let _ = Vector::empty<u64>();
}
}
모듈 또한 스크립트처럼 블럭 안에서 명시하면 된다.
Import 구문을 확장해서, 모듈 중 가져오길 원하는 특정 멤버만 가져올 수 있는 방법이 있다.
[Member Import]
script {
// single member import
use 0x1::Signer::address_of;
// multi member import (mind braces)
use 0x1::Vector::{
empty,
push_back
};
fun main(acc: &signer) {
// use functions without module access
let vec = empty<u8>();
push_back(&mut vec, 10);
// same here
let _ = address_of(acc);
}
}
이름에서 충돌이 일어나는 것을 방지하기 위하여 Import를 할 대 as
를 사용해서 미리 모듈 이름을 변경하여 가져올 수 있다.