diff --git a/abilities.html b/abilities.html index 30a8b00d6f..081c454ea7 100644 --- a/abilities.html +++ b/abilities.html @@ -270,7 +270,7 @@
copy
-struct NoAbilities {}
+struct NoAbilities {}
struct S has copy, drop { f: bool }
struct Cup<T> has copy, drop, store { item: T }
@@ -292,7 +292,7 @@ Example: conditional drop
-struct NoAbilities {}
+struct NoAbilities {}
struct S has copy, drop { f: bool }
struct Cup<T> has copy, drop, store { item: T }
@@ -318,13 +318,13 @@ Example: conditional store
-struct Cup<T> has copy, drop, store { item: T }
+struct Cup<T> has copy, drop, store { item: T }
// 'MyInnerResource' is declared with 'store' so all fields need 'store'
struct MyInnerResource has store {
@@ -340,7 +340,7 @@ Example: conditional key
-struct NoAbilities {}
+struct NoAbilities {}
struct MyResource<T> has key { f: T }
fun valid(account: &signer) acquires MyResource {
diff --git a/coding-conventions.html b/coding-conventions.html
index 38c9ee5215..505ddf7707 100644
--- a/coding-conventions.html
+++ b/coding-conventions.html
@@ -159,7 +159,7 @@ Naming
Constant names: should be upper camel case and begin with an E
if they represent error codes (e.g., EIndexOutOfBounds
) and upper snake case if they represent a non-error value (e.g., MIN_STAKE
).
Generic type names: should be descriptive, or anti-descriptive where appropriate, e.g., T
or Element
for the Vector generic type parameter. Most of the time the "main" type in a module should be the same name as the module e.g., option::Option
, fixed_point32::FixedPoint32
.
-Module file names: should be the same as the module name e.g., option.move
.
+Module file names: should be the same as the module name e.g., Option.move
.
Script file names: should be lower snake case and should match the name of the “main” function in the script.
Mixed file names: If the file contains multiple modules and/or scripts, the file name should be lower snake case, where the name does not match any particular module/script inside.
diff --git a/functions.html b/functions.html
index 44ac339392..79bc2cd18a 100644
--- a/functions.html
+++ b/functions.html
@@ -189,7 +189,6 @@ pub
functions defined in another module, or
the function defined in a script.
-There are also no restrictions for what the argument types a public function can take and its return type.
address 0x42 {
module m {
public fun foo(): u64 { 0 }
@@ -302,13 +301,12 @@ entry
-Entry functions can take primitive types, String, and vector arguments but cannot take Structs (e.g. Option). They also
-must not have any return values.
Name
Function names can start with letters a
to z
or letters A
to Z
. After the first character, function names can contain underscores _
, letters a
to z
, letters A
to Z
, or digits 0
to 9
.
fun FOO() {}
fun bar_42() {}
fun _bAZ19() {}
+ ^^^^^^ Invalid function name '_bAZ19'. Function names cannot start with '_'
Type Parameters
After the name, functions can have type parameters
@@ -544,38 +542,6 @@ ret
fun foo() { return }
fun foo() { return () }
-Inline Functions
-Inline functions are functions which are expanded at caller side instead
-of compiled into Move bytecode. This allows to safe gas and may lead
-to faster execution. For example, one can define an inline function
-inline fun percent(x: u64, y: u64):u64 { x * 100 / y }
-
-Now, when call percent(2, 200)
the compiler will inline the function
-definition as if the user has written 2 * 100 / 200
.
-Function Parameters
-Inline functions support function parameters. This allows
-to define higher-order functions in Move which can comprehend common
-programming patterns. As inline functions are expanded at compilation time,
-this feature of function parameters can be supported without direct
-support for it in Move bytecode.
-Consider the following function (from the vector
module):
-/// Fold the function over the elements. For example, `fold(vector[1,2,3], 0, f)` will execute
-/// `f(f(f(0, 1), 2), 3)`
-public inline fun fold<Accumulator, Element>(
- v: vector<Element>,
- init: Accumulator,
- f: |Accumulator,Element|Accumulator
-): Accumulator {
- let accu = init;
- foreach(v, |elem| accu = g(accu, elem));
- accu
-}
-
-Here, foreach
is itself an inline function.
-In general, only lambda expressions can be passed to function parameters.
-Similar as the inline function itself, those lambdas are expanded at caller
-side. Notice that a lambda can access variables in the context, as in the
-example the variable accu
.
diff --git a/print.html b/print.html
index a971af1d3d..81d14faf7a 100644
--- a/print.html
+++ b/print.html
@@ -1964,7 +1964,6 @@ pub
functions defined in another module, or
the function defined in a script.
-There are also no restrictions for what the argument types a public function can take and its return type.
address 0x42 {
module m {
public fun foo(): u64 { 0 }
@@ -2077,13 +2076,12 @@ entry
-Entry functions can take primitive types, String, and vector arguments but cannot take Structs (e.g. Option). They also
-must not have any return values.
Name
Function names can start with letters a
to z
or letters A
to Z
. After the first character, function names can contain underscores _
, letters a
to z
, letters A
to Z
, or digits 0
to 9
.
fun FOO() {}
fun bar_42() {}
fun _bAZ19() {}
+ ^^^^^^ Invalid function name '_bAZ19'. Function names cannot start with '_'
Type Parameters
After the name, functions can have type parameters
@@ -2319,38 +2317,6 @@ ret
fun foo() { return }
fun foo() { return () }
-Inline Functions
-Inline functions are functions which are expanded at caller side instead
-of compiled into Move bytecode. This allows to safe gas and may lead
-to faster execution. For example, one can define an inline function
-inline fun percent(x: u64, y: u64):u64 { x * 100 / y }
-
-Now, when call percent(2, 200)
the compiler will inline the function
-definition as if the user has written 2 * 100 / 200
.
-Function Parameters
-Inline functions support function parameters. This allows
-to define higher-order functions in Move which can comprehend common
-programming patterns. As inline functions are expanded at compilation time,
-this feature of function parameters can be supported without direct
-support for it in Move bytecode.
-Consider the following function (from the vector
module):
-/// Fold the function over the elements. For example, `fold(vector[1,2,3], 0, f)` will execute
-/// `f(f(f(0, 1), 2), 3)`
-public inline fun fold<Accumulator, Element>(
- v: vector<Element>,
- init: Accumulator,
- f: |Accumulator,Element|Accumulator
-): Accumulator {
- let accu = init;
- foreach(v, |elem| accu = g(accu, elem));
- accu
-}
-
-Here, foreach
is itself an inline function.
-In general, only lambda expressions can be passed to function parameters.
-Similar as the inline function itself, those lambdas are expanded at caller
-side. Notice that a lambda can access variables in the context, as in the
-example the variable accu
.
Structs and Resources
A struct is a user-defined data structure containing typed fields. Structs can store any
non-reference type, including other structs.
@@ -3356,7 +3322,7 @@ Example: conditional copy
-struct NoAbilities {}
+struct NoAbilities {}
struct S has copy, drop { f: bool }
struct Cup<T> has copy, drop, store { item: T }
@@ -3378,7 +3344,7 @@ Example: conditional drop
-struct NoAbilities {}
+struct NoAbilities {}
struct S has copy, drop { f: bool }
struct Cup<T> has copy, drop, store { item: T }
@@ -3404,13 +3370,13 @@ Example: conditional store
-struct Cup<T> has copy, drop, store { item: T }
+struct Cup<T> has copy, drop, store { item: T }
// 'MyInnerResource' is declared with 'store' so all fields need 'store'
struct MyInnerResource has store {
@@ -3426,7 +3392,7 @@ Example: conditional key
-struct NoAbilities {}
+struct NoAbilities {}
struct MyResource<T> has key { f: T }
fun valid(account: &signer) acquires MyResource {
@@ -4772,7 +4738,7 @@ Constants
const INVALID_STATE: u8 = 1;
-A specific account address was required to perform an operation, but a different address from what was expected was encountered.
+A specific account address was required to perform an operation, but a different address from what was expected was encounterd.
const REQUIRES_ADDRESS: u8 = 2;
@@ -4890,7 +4856,7 @@ Naming
Constant names: should be upper camel case and begin with an E
if they represent error codes (e.g., EIndexOutOfBounds
) and upper snake case if they represent a non-error value (e.g., MIN_STAKE
).
Generic type names: should be descriptive, or anti-descriptive where appropriate, e.g., T
or Element
for the Vector generic type parameter. Most of the time the "main" type in a module should be the same name as the module e.g., option::Option
, fixed_point32::FixedPoint32
.
-Module file names: should be the same as the module name e.g., option.move
.
+Module file names: should be the same as the module name e.g., Option.move
.
Script file names: should be lower snake case and should match the name of the “main” function in the script.
Mixed file names: If the file contains multiple modules and/or scripts, the file name should be lower snake case, where the name does not match any particular module/script inside.
diff --git a/searchindex.js b/searchindex.js
index 81717dc5dd..ca86be008e 100644
--- a/searchindex.js
+++ b/searchindex.js
@@ -1 +1 @@
-Object.assign(window.search, {"doc_urls":["introduction.html#introduction","introduction.html#who-is-move-for","introduction.html#hobbyists","introduction.html#core-contributor","introduction.html#who-move-is-currently-not-targeting","introduction.html#where-do-i-start","modules-and-scripts.html#modules-and-scripts","modules-and-scripts.html#syntax","modules-and-scripts.html#scripts","modules-and-scripts.html#modules","creating-coins.html#move-tutorial","integers.html#integers","integers.html#literals","integers.html#examples","integers.html#operations","integers.html#arithmetic","integers.html#bitwise","integers.html#bit-shifts","integers.html#comparisons","integers.html#equality","integers.html#casting","integers.html#ownership","bool.html#bool","bool.html#literals","bool.html#operations","bool.html#logical","bool.html#control-flow","bool.html#ownership","address.html#address","address.html#addresses-and-their-syntax","address.html#named-addresses","address.html#examples","address.html#global-storage-operations","address.html#ownership","vector.html#vector","vector.html#literals","vector.html#general-vector-literals","vector.html#vectoru8-literals","vector.html#operations","vector.html#example","vector.html#destroying-and-copying-vectors","vector.html#ownership","signer.html#signer","signer.html#comparison-to-address","signer.html#signer-operators","signer.html#ownership","references.html#references","references.html#reference-operators","references.html#reading-and-writing-through-references","references.html#freeze-inference","references.html#subtyping","references.html#ownership","references.html#references-cannot-be-stored","tuples.html#tuples-and-unit","tuples.html#literals","tuples.html#examples","tuples.html#operations","tuples.html#destructuring","tuples.html#subtyping","tuples.html#ownership","variables.html#local-variables-and-scope","variables.html#declaring-local-variables","variables.html#let-bindings","variables.html#variables-must-be-assigned-before-use","variables.html#valid-variable-names","variables.html#type-annotations","variables.html#when-annotations-are-necessary","variables.html#multiple-declarations-with-tuples","variables.html#multiple-declarations-with-structs","variables.html#destructuring-against-references","variables.html#ignoring-values","variables.html#general-let-grammar","variables.html#mutations","variables.html#assignments","variables.html#mutating-through-a-reference","variables.html#scopes","variables.html#expression-blocks","variables.html#shadowing","variables.html#move-and-copy","variables.html#safety","variables.html#inference","equality.html#equality","equality.html#operations","equality.html#typing","equality.html#typing-with-references","equality.html#restrictions","equality.html#avoid-extra-copies","abort-and-assert.html#abort-and-assert","abort-and-assert.html#abort","abort-and-assert.html#assert","abort-and-assert.html#abort-codes-in-the-move-vm","abort-and-assert.html#the-type-of-abort","conditionals.html#conditionals","conditionals.html#grammar-for-conditionals","loops.html#while-and-loop","loops.html#while-loops","loops.html#break","loops.html#continue","loops.html#the-type-of-break-and-continue","loops.html#the-loop-expression","loops.html#the-type-of-while-and-loop","functions.html#functions","functions.html#declaration","functions.html#visibility","functions.html#entry-modifier","functions.html#name","functions.html#type-parameters","functions.html#parameters","functions.html#acquires","functions.html#return-type","functions.html#function-body","functions.html#native-functions","functions.html#calling","functions.html#returning-values","functions.html#return-expression","functions.html#inline-functions","functions.html#function-parameters","structs-and-resources.html#structs-and-resources","structs-and-resources.html#defining-structs","structs-and-resources.html#naming","structs-and-resources.html#using-structs","structs-and-resources.html#creating-structs","structs-and-resources.html#destroying-structs-via-pattern-matching","structs-and-resources.html#borrowing-structs-and-fields","structs-and-resources.html#reading-and-writing-fields","structs-and-resources.html#privileged-struct-operations","structs-and-resources.html#ownership","structs-and-resources.html#storing-resources-in-global-storage","structs-and-resources.html#examples","structs-and-resources.html#example-1-coin","structs-and-resources.html#example-2-geometry","constants.html#constants","constants.html#declaration","constants.html#naming","constants.html#visibility","constants.html#valid-expressions","constants.html#values","constants.html#complex-expressions","generics.html#generics","generics.html#declaring-type-parameters","generics.html#generic-functions","generics.html#generic-structs","generics.html#type-arguments","generics.html#calling-generic-functions","generics.html#using-generic-structs","generics.html#type-argument-mismatch","generics.html#type-inference","generics.html#unused-type-parameters","generics.html#phantom-type-parameters","generics.html#constraints","generics.html#declaring-constraints","generics.html#verifying-constraints","generics.html#limitations-on-recursions","generics.html#recursive-structs","generics.html#advanced-topic-type-level-recursions","abilities.html#abilities","abilities.html#the-four-abilities","abilities.html#copy","abilities.html#drop","abilities.html#store","abilities.html#key","abilities.html#builtin-types","abilities.html#annotating-structs","abilities.html#conditional-abilities-and-generic-types","abilities.html#example-conditional-copy","abilities.html#example-conditional-drop","abilities.html#example-conditional-store","abilities.html#example-conditional-key","uses.html#uses-and-aliases","uses.html#syntax","uses.html#inside-a-module","uses.html#inside-an-expression","uses.html#naming-rules","uses.html#uniqueness","uses.html#shadowing","uses.html#unused-use-or-alias","friends.html#friends","friends.html#friend-declaration","friends.html#friend-declaration-rules","packages.html#packages","packages.html#package-layout-and-manifest-syntax","packages.html#movetoml","packages.html#named-addresses-during-compilation","packages.html#declaration","packages.html#scoping-and-renaming-of-named-addresses","packages.html#instantiation","packages.html#usage-artifacts-and-data-structures","packages.html#usage","unit-testing.html#unit-tests","unit-testing.html#testing-annotations-their-meaning-and-usage","unit-testing.html#running-unit-tests","unit-testing.html#example","unit-testing.html#running-tests","unit-testing.html#using-test-flags","global-storage-structure.html#global-storage---structure","global-storage-operators.html#global-storage---operators","global-storage-operators.html#references-to-resources","global-storage-operators.html#global-storage-operators-with-generics","global-storage-operators.html#example-counter","global-storage-operators.html#annotating-functions-with-acquires","global-storage-operators.html#reference-safety-for-global-resources","standard-library.html#standard-library","standard-library.html#vector","standard-library.html#functions","standard-library.html#option","standard-library.html#types","standard-library.html#functions","standard-library.html#errors","standard-library.html#constants","standard-library.html#functions","standard-library.html#fixed_point32","standard-library.html#types","standard-library.html#functions","coding-conventions.html#move-coding-conventions","coding-conventions.html#naming","coding-conventions.html#imports","coding-conventions.html#comments","coding-conventions.html#formatting"],"index":{"documentStore":{"docInfo":{"0":{"body":61,"breadcrumbs":2,"title":1},"1":{"body":41,"breadcrumbs":2,"title":1},"10":{"body":4,"breadcrumbs":4,"title":2},"100":{"body":38,"breadcrumbs":3,"title":2},"101":{"body":20,"breadcrumbs":2,"title":1},"102":{"body":40,"breadcrumbs":2,"title":1},"103":{"body":207,"breadcrumbs":2,"title":1},"104":{"body":164,"breadcrumbs":3,"title":2},"105":{"body":27,"breadcrumbs":2,"title":1},"106":{"body":28,"breadcrumbs":3,"title":2},"107":{"body":47,"breadcrumbs":2,"title":1},"108":{"body":195,"breadcrumbs":2,"title":1},"109":{"body":69,"breadcrumbs":3,"title":2},"11":{"body":71,"breadcrumbs":2,"title":1},"110":{"body":34,"breadcrumbs":3,"title":2},"111":{"body":48,"breadcrumbs":3,"title":2},"112":{"body":112,"breadcrumbs":2,"title":1},"113":{"body":52,"breadcrumbs":3,"title":2},"114":{"body":114,"breadcrumbs":3,"title":2},"115":{"body":43,"breadcrumbs":3,"title":2},"116":{"body":95,"breadcrumbs":3,"title":2},"117":{"body":80,"breadcrumbs":4,"title":2},"118":{"body":80,"breadcrumbs":4,"title":2},"119":{"body":37,"breadcrumbs":3,"title":1},"12":{"body":48,"breadcrumbs":2,"title":1},"120":{"body":0,"breadcrumbs":4,"title":2},"121":{"body":66,"breadcrumbs":4,"title":2},"122":{"body":166,"breadcrumbs":7,"title":5},"123":{"body":85,"breadcrumbs":5,"title":3},"124":{"body":214,"breadcrumbs":5,"title":3},"125":{"body":101,"breadcrumbs":5,"title":3},"126":{"body":198,"breadcrumbs":3,"title":1},"127":{"body":23,"breadcrumbs":6,"title":4},"128":{"body":17,"breadcrumbs":3,"title":1},"129":{"body":131,"breadcrumbs":5,"title":3},"13":{"body":97,"breadcrumbs":2,"title":1},"130":{"body":103,"breadcrumbs":5,"title":3},"131":{"body":27,"breadcrumbs":2,"title":1},"132":{"body":43,"breadcrumbs":2,"title":1},"133":{"body":61,"breadcrumbs":2,"title":1},"134":{"body":9,"breadcrumbs":2,"title":1},"135":{"body":24,"breadcrumbs":3,"title":2},"136":{"body":25,"breadcrumbs":2,"title":1},"137":{"body":101,"breadcrumbs":3,"title":2},"138":{"body":56,"breadcrumbs":2,"title":1},"139":{"body":12,"breadcrumbs":4,"title":3},"14":{"body":0,"breadcrumbs":2,"title":1},"140":{"body":45,"breadcrumbs":3,"title":2},"141":{"body":29,"breadcrumbs":3,"title":2},"142":{"body":0,"breadcrumbs":3,"title":2},"143":{"body":26,"breadcrumbs":4,"title":3},"144":{"body":30,"breadcrumbs":4,"title":3},"145":{"body":33,"breadcrumbs":4,"title":3},"146":{"body":94,"breadcrumbs":3,"title":2},"147":{"body":111,"breadcrumbs":4,"title":3},"148":{"body":369,"breadcrumbs":4,"title":3},"149":{"body":56,"breadcrumbs":2,"title":1},"15":{"body":79,"breadcrumbs":2,"title":1},"150":{"body":38,"breadcrumbs":3,"title":2},"151":{"body":89,"breadcrumbs":3,"title":2},"152":{"body":0,"breadcrumbs":3,"title":2},"153":{"body":49,"breadcrumbs":3,"title":2},"154":{"body":158,"breadcrumbs":6,"title":5},"155":{"body":43,"breadcrumbs":3,"title":1},"156":{"body":32,"breadcrumbs":4,"title":2},"157":{"body":29,"breadcrumbs":3,"title":1},"158":{"body":52,"breadcrumbs":3,"title":1},"159":{"body":37,"breadcrumbs":3,"title":1},"16":{"body":44,"breadcrumbs":2,"title":1},"160":{"body":46,"breadcrumbs":3,"title":1},"161":{"body":71,"breadcrumbs":4,"title":2},"162":{"body":117,"breadcrumbs":4,"title":2},"163":{"body":160,"breadcrumbs":6,"title":4},"164":{"body":64,"breadcrumbs":5,"title":3},"165":{"body":88,"breadcrumbs":5,"title":3},"166":{"body":48,"breadcrumbs":5,"title":3},"167":{"body":57,"breadcrumbs":5,"title":3},"168":{"body":18,"breadcrumbs":4,"title":2},"169":{"body":256,"breadcrumbs":3,"title":1},"17":{"body":68,"breadcrumbs":3,"title":2},"170":{"body":45,"breadcrumbs":4,"title":2},"171":{"body":101,"breadcrumbs":4,"title":2},"172":{"body":40,"breadcrumbs":4,"title":2},"173":{"body":67,"breadcrumbs":3,"title":1},"174":{"body":99,"breadcrumbs":3,"title":1},"175":{"body":19,"breadcrumbs":5,"title":3},"176":{"body":26,"breadcrumbs":2,"title":1},"177":{"body":138,"breadcrumbs":3,"title":2},"178":{"body":180,"breadcrumbs":4,"title":3},"179":{"body":48,"breadcrumbs":2,"title":1},"18":{"body":32,"breadcrumbs":2,"title":1},"180":{"body":112,"breadcrumbs":5,"title":4},"181":{"body":257,"breadcrumbs":2,"title":1},"182":{"body":46,"breadcrumbs":5,"title":4},"183":{"body":144,"breadcrumbs":2,"title":1},"184":{"body":188,"breadcrumbs":5,"title":4},"185":{"body":78,"breadcrumbs":2,"title":1},"186":{"body":34,"breadcrumbs":5,"title":4},"187":{"body":72,"breadcrumbs":2,"title":1},"188":{"body":48,"breadcrumbs":4,"title":2},"189":{"body":302,"breadcrumbs":6,"title":4},"19":{"body":35,"breadcrumbs":2,"title":1},"190":{"body":92,"breadcrumbs":5,"title":3},"191":{"body":123,"breadcrumbs":3,"title":1},"192":{"body":31,"breadcrumbs":4,"title":2},"193":{"body":254,"breadcrumbs":5,"title":3},"194":{"body":66,"breadcrumbs":6,"title":3},"195":{"body":99,"breadcrumbs":6,"title":3},"196":{"body":75,"breadcrumbs":5,"title":2},"197":{"body":67,"breadcrumbs":7,"title":4},"198":{"body":178,"breadcrumbs":5,"title":2},"199":{"body":181,"breadcrumbs":6,"title":3},"2":{"body":42,"breadcrumbs":2,"title":1},"20":{"body":70,"breadcrumbs":2,"title":1},"200":{"body":238,"breadcrumbs":7,"title":4},"201":{"body":29,"breadcrumbs":4,"title":2},"202":{"body":26,"breadcrumbs":3,"title":1},"203":{"body":311,"breadcrumbs":3,"title":1},"204":{"body":62,"breadcrumbs":3,"title":1},"205":{"body":12,"breadcrumbs":3,"title":1},"206":{"body":270,"breadcrumbs":3,"title":1},"207":{"body":146,"breadcrumbs":3,"title":1},"208":{"body":103,"breadcrumbs":3,"title":1},"209":{"body":232,"breadcrumbs":3,"title":1},"21":{"body":15,"breadcrumbs":2,"title":1},"210":{"body":61,"breadcrumbs":3,"title":1},"211":{"body":10,"breadcrumbs":3,"title":1},"212":{"body":152,"breadcrumbs":3,"title":1},"213":{"body":19,"breadcrumbs":5,"title":3},"214":{"body":107,"breadcrumbs":3,"title":1},"215":{"body":75,"breadcrumbs":3,"title":1},"216":{"body":19,"breadcrumbs":3,"title":1},"217":{"body":31,"breadcrumbs":3,"title":1},"22":{"body":8,"breadcrumbs":2,"title":1},"23":{"body":4,"breadcrumbs":2,"title":1},"24":{"body":0,"breadcrumbs":2,"title":1},"25":{"body":34,"breadcrumbs":2,"title":1},"26":{"body":12,"breadcrumbs":3,"title":2},"27":{"body":15,"breadcrumbs":2,"title":1},"28":{"body":83,"breadcrumbs":2,"title":1},"29":{"body":82,"breadcrumbs":3,"title":2},"3":{"body":34,"breadcrumbs":3,"title":2},"30":{"body":77,"breadcrumbs":3,"title":2},"31":{"body":61,"breadcrumbs":2,"title":1},"32":{"body":24,"breadcrumbs":4,"title":3},"33":{"body":15,"breadcrumbs":2,"title":1},"34":{"body":27,"breadcrumbs":2,"title":1},"35":{"body":0,"breadcrumbs":2,"title":1},"36":{"body":70,"breadcrumbs":4,"title":3},"37":{"body":146,"breadcrumbs":3,"title":2},"38":{"body":196,"breadcrumbs":2,"title":1},"39":{"body":26,"breadcrumbs":2,"title":1},"4":{"body":24,"breadcrumbs":4,"title":3},"40":{"body":102,"breadcrumbs":4,"title":3},"41":{"body":13,"breadcrumbs":2,"title":1},"42":{"body":37,"breadcrumbs":2,"title":1},"43":{"body":103,"breadcrumbs":3,"title":2},"44":{"body":49,"breadcrumbs":3,"title":2},"45":{"body":17,"breadcrumbs":2,"title":1},"46":{"body":38,"breadcrumbs":2,"title":1},"47":{"body":148,"breadcrumbs":3,"title":2},"48":{"body":124,"breadcrumbs":5,"title":4},"49":{"body":84,"breadcrumbs":3,"title":2},"5":{"body":8,"breadcrumbs":2,"title":1},"50":{"body":131,"breadcrumbs":2,"title":1},"51":{"body":53,"breadcrumbs":2,"title":1},"52":{"body":139,"breadcrumbs":3,"title":2},"53":{"body":125,"breadcrumbs":4,"title":2},"54":{"body":68,"breadcrumbs":3,"title":1},"55":{"body":45,"breadcrumbs":3,"title":1},"56":{"body":5,"breadcrumbs":3,"title":1},"57":{"body":87,"breadcrumbs":3,"title":1},"58":{"body":75,"breadcrumbs":3,"title":1},"59":{"body":25,"breadcrumbs":3,"title":1},"6":{"body":75,"breadcrumbs":4,"title":2},"60":{"body":23,"breadcrumbs":6,"title":3},"61":{"body":0,"breadcrumbs":6,"title":3},"62":{"body":48,"breadcrumbs":4,"title":1},"63":{"body":28,"breadcrumbs":7,"title":4},"64":{"body":43,"breadcrumbs":6,"title":3},"65":{"body":90,"breadcrumbs":5,"title":2},"66":{"body":109,"breadcrumbs":5,"title":2},"67":{"body":65,"breadcrumbs":6,"title":3},"68":{"body":135,"breadcrumbs":6,"title":3},"69":{"body":152,"breadcrumbs":6,"title":3},"7":{"body":0,"breadcrumbs":3,"title":1},"70":{"body":48,"breadcrumbs":5,"title":2},"71":{"body":129,"breadcrumbs":5,"title":2},"72":{"body":0,"breadcrumbs":4,"title":1},"73":{"body":121,"breadcrumbs":4,"title":1},"74":{"body":73,"breadcrumbs":6,"title":3},"75":{"body":66,"breadcrumbs":4,"title":1},"76":{"body":180,"breadcrumbs":5,"title":2},"77":{"body":137,"breadcrumbs":4,"title":1},"78":{"body":100,"breadcrumbs":5,"title":2},"79":{"body":21,"breadcrumbs":4,"title":1},"8":{"body":79,"breadcrumbs":3,"title":1},"80":{"body":100,"breadcrumbs":4,"title":1},"81":{"body":5,"breadcrumbs":2,"title":1},"82":{"body":21,"breadcrumbs":2,"title":1},"83":{"body":92,"breadcrumbs":2,"title":1},"84":{"body":64,"breadcrumbs":3,"title":2},"85":{"body":95,"breadcrumbs":2,"title":1},"86":{"body":82,"breadcrumbs":4,"title":3},"87":{"body":20,"breadcrumbs":4,"title":2},"88":{"body":127,"breadcrumbs":3,"title":1},"89":{"body":111,"breadcrumbs":3,"title":1},"9":{"body":197,"breadcrumbs":3,"title":1},"90":{"body":168,"breadcrumbs":6,"title":4},"91":{"body":44,"breadcrumbs":4,"title":2},"92":{"body":137,"breadcrumbs":2,"title":1},"93":{"body":7,"breadcrumbs":3,"title":2},"94":{"body":6,"breadcrumbs":2,"title":1},"95":{"body":40,"breadcrumbs":2,"title":1},"96":{"body":39,"breadcrumbs":2,"title":1},"97":{"body":40,"breadcrumbs":2,"title":1},"98":{"body":85,"breadcrumbs":4,"title":3},"99":{"body":70,"breadcrumbs":3,"title":2}},"docs":{"0":{"body":"Welcome to Move, a next generation language for secure, sandboxed, and formally verified programming. Its first use case is for the Diem blockchain, where Move provides the foundation for its implementation. Move allows developers to write programs that flexibly manage and transfer assets, while providing the security and protections against attacks on those assets. However, Move has been developed with use cases in mind outside a blockchain context as well. Move takes its cue from Rust by using resource types with move (hence the name) semantics as an explicit representation of digital assets, such as currency.","breadcrumbs":"Introduction » Introduction","id":"0","title":"Introduction"},"1":{"body":"Move was designed and created as a secure, verified, yet flexible programming language. The first use of Move is for the implementation of the Diem blockchain. That said, the language is still evolving. Move has the potential to be a language for other blockchains, and even non-blockchain use cases as well. The early Move Developer is one with some programming experience, who wants to begin understanding the core programming language and see examples of its usage.","breadcrumbs":"Introduction » Who is Move for?","id":"1","title":"Who is Move for?"},"10":{"body":"Please refer to the Move Tutorial .","breadcrumbs":"Move Tutorial » Move Tutorial","id":"10","title":"Move Tutorial"},"100":{"body":"Move loops are typed expressions. A while expression always has type (). let () = while (i < 10) { i = i + 1 }; If a loop contains a break, the expression has type unit () (loop { if (i < 10) i = i + 1 else break }: ());\nlet () = loop { if (i < 10) i = i + 1 else break }; If loop does not have a break, loop can have any type much like return, abort, break, and continue. (loop (): u64);\n(loop (): address);\n(loop (): &vector>);","breadcrumbs":"While and Loop » The type of while and loop","id":"100","title":"The type of while and loop"},"101":{"body":"Function syntax in Move is shared between module functions and script functions. Functions inside of modules are reusable, whereas script functions are only used once to invoke a transaction.","breadcrumbs":"Functions » Functions","id":"101","title":"Functions"},"102":{"body":"Functions are declared with the fun keyword followed by the function name, type parameters, parameters, a return type, acquires annotations, and finally the function body. fun <[type_parameters: constraint],*>([identifier: type],*): For example fun foo(x: u64, y: T1, z: T2): (T2, T1, u64) { (z, y, x) }","breadcrumbs":"Functions » Declaration","id":"102","title":"Declaration"},"103":{"body":"Module functions, by default, can only be called within the same module. These internal (sometimes called private) functions cannot be called from other modules or from scripts. address 0x42 {\nmodule m { fun foo(): u64 { 0 } fun calls_foo(): u64 { foo() } // valid\n} module other { fun calls_m_foo(): u64 { 0x42::m::foo() // ERROR!\n// ^^^^^^^^^^^^ 'foo' is internal to '0x42::m' }\n}\n} script { fun calls_m_foo(): u64 { 0x42::m::foo() // ERROR!\n// ^^^^^^^^^^^^ 'foo' is internal to '0x42::m' }\n} To allow access from other modules or from scripts, the function must be declared public or public(friend). public visibility A public function can be called by any function defined in any module or script. As shown in the following example, a public function can be called by: other functions defined in the same module, functions defined in another module, or the function defined in a script. There are also no restrictions for what the argument types a public function can take and its return type. address 0x42 {\nmodule m { public fun foo(): u64 { 0 } fun calls_foo(): u64 { foo() } // valid\n} module other { fun calls_m_foo(): u64 { 0x42::m::foo() // valid }\n}\n} script { fun calls_m_foo(): u64 { 0x42::m::foo() // valid }\n} public(friend) visibility The public(friend) visibility modifier is a more restricted form of the public modifier to give more control about where a function can be used. A public(friend) function can be called by: other functions defined in the same module, or functions defined in modules which are explicitly specified in the friend list (see Friends on how to specify the friend list). Note that since we cannot declare a script to be a friend of a module, the functions defined in scripts can never call a public(friend) function. address 0x42 {\nmodule m { friend 0x42::n; // friend declaration public(friend) fun foo(): u64 { 0 } fun calls_foo(): u64 { foo() } // valid\n} module n { fun calls_m_foo(): u64 { 0x42::m::foo() // valid }\n} module other { fun calls_m_foo(): u64 { 0x42::m::foo() // ERROR!\n// ^^^^^^^^^^^^ 'foo' can only be called from a 'friend' of module '0x42::m' }\n}\n} script { fun calls_m_foo(): u64 { 0x42::m::foo() // ERROR!\n// ^^^^^^^^^^^^ 'foo' can only be called from a 'friend' of module '0x42::m' }\n}","breadcrumbs":"Functions » Visibility","id":"103","title":"Visibility"},"104":{"body":"The entry modifier is designed to allow module functions to be safely and directly invoked much like scripts. This allows module writers to specify which functions can be to begin execution. The module writer then knows that any non-entry function will be called from a Move program already in execution. Essentially, entry functions are the \"main\" functions of a module, and they specify where Move programs start executing. Note though, an entry function can still be called by other Move functions. So while they can serve as the start of a Move program, they aren't restricted to that case. For example: address 0x42 {\nmodule m { public entry fun foo(): u64 { 0 } fun calls_foo(): u64 { foo() } // valid!\n} module n { fun calls_m_foo(): u64 { 0x42::m::foo() // valid! }\n} module other { public entry fun calls_m_foo(): u64 { 0x42::m::foo() // valid! }\n}\n} script { fun calls_m_foo(): u64 { 0x42::m::foo() // valid! }\n} Even internal functions can be marked as entry! This lets you guarantee that the function is called only at the beginning of execution (assuming you do not call it elsewhere in your module) address 0x42 {\nmodule m { entry fun foo(): u64 { 0 } // valid! entry functions do not have to be public\n} module n { fun calls_m_foo(): u64 { 0x42::m::foo() // ERROR!\n// ^^^^^^^^^^^^ 'foo' is internal to '0x42::m' }\n} module other { public entry fun calls_m_foo(): u64 { 0x42::m::foo() // ERROR!\n// ^^^^^^^^^^^^ 'foo' is internal to '0x42::m' }\n}\n} script { fun calls_m_foo(): u64 { 0x42::m::foo() // ERROR!\n// ^^^^^^^^^^^^ 'foo' is internal to '0x42::m' }\n} Entry functions can take primitive types, String, and vector arguments but cannot take Structs (e.g. Option). They also must not have any return values.","breadcrumbs":"Functions » entry modifier","id":"104","title":"entry modifier"},"105":{"body":"Function names can start with letters a to z or letters A to Z. After the first character, function names can contain underscores _, letters a to z, letters A to Z, or digits 0 to 9. fun FOO() {}\nfun bar_42() {}\nfun _bAZ19() {}","breadcrumbs":"Functions » Name","id":"105","title":"Name"},"106":{"body":"After the name, functions can have type parameters fun id(x: T): T { x }\nfun example(x: T1, y: T2): (T1, T1, T2) { (copy x, x, y) } For more details, see Move generics .","breadcrumbs":"Functions » Type Parameters","id":"106","title":"Type Parameters"},"107":{"body":"Functions parameters are declared with a local variable name followed by a type annotation fun add(x: u64, y: u64): u64 { x + y } We read this as x has type u64 A function does not have to have any parameters at all. fun useless() { } This is very common for functions that create new or empty data structures address 0x42 {\nmodule example { struct Counter { count: u64 } fun new_counter(): Counter { Counter { count: 0 } } }\n}","breadcrumbs":"Functions » Parameters","id":"107","title":"Parameters"},"108":{"body":"When a function accesses a resource using move_from, borrow_global, or borrow_global_mut, the function must indicate that it acquires that resource. This is then used by Move's type system to ensure the references into global storage are safe, specifically that there are no dangling references into global storage. address 0x42 {\nmodule example { struct Balance has key { value: u64 } public fun add_balance(s: &signer, value: u64) { move_to(s, Balance { value }) } public fun extract_balance(addr: address): u64 acquires Balance { let Balance { value } = move_from(addr); // acquires needed value }\n}\n} acquires annotations must also be added for transitive calls within the module. Calls to these functions from another module do not need to annotated with these acquires because one module cannot access resources declared in another module--so the annotation is not needed to ensure reference safety. address 0x42 {\nmodule example { struct Balance has key { value: u64 } public fun add_balance(s: &signer, value: u64) { move_to(s, Balance { value }) } public fun extract_balance(addr: address): u64 acquires Balance { let Balance { value } = move_from(addr); // acquires needed value } public fun extract_and_add(sender: address, receiver: &signer) acquires Balance { let value = extract_balance(sender); // acquires needed here add_balance(receiver, value) }\n}\n} address 0x42 {\nmodule other { fun extract_balance(addr: address): u64 { 0x42::example::extract_balance(addr) // no acquires needed }\n}\n} A function can acquire as many resources as it needs to address 0x42 {\nmodule example { use std::vector; struct Balance has key { value: u64 } struct Box has key { items: vector } public fun store_two( addr: address, item1: Item1, item2: Item2, ) acquires Balance, Box { let balance = borrow_global_mut(addr); // acquires needed balance.value = balance.value - 2; let box1 = borrow_global_mut>(addr); // acquires needed vector::push_back(&mut box1.items, item1); let box2 = borrow_global_mut>(addr); // acquires needed vector::push_back(&mut box2.items, item2); }\n}\n}","breadcrumbs":"Functions » Acquires","id":"108","title":"Acquires"},"109":{"body":"After the parameters, a function specifies its return type. fun zero(): u64 { 0 } Here : u64 indicates that the function's return type is u64. Using tuples, a function can return multiple values: fun one_two_three(): (u64, u64, u64) { (0, 1, 2) } If no return type is specified, the function has an implicit return type of unit (). These functions are equivalent: fun just_unit(): () { () }\nfun just_unit() { () }\nfun just_unit() { } script functions must have a return type of unit (): script { fun do_nothing() { }\n} As mentioned in the tuples section , these tuple \"values\" are virtual and do not exist at runtime. So for a function that returns unit (), it will not be returning any value at all during execution.","breadcrumbs":"Functions » Return type","id":"109","title":"Return type"},"11":{"body":"Move supports six unsigned integer types: u8, u16, u32, u64, u128, and u256. Values of these types range from 0 to a maximum that depends on the size of the type. Type Value Range Unsigned 8-bit integer, u8 0 to 28 - 1 Unsigned 16-bit integer, u16 0 to 216 - 1 Unsigned 32-bit integer, u32 0 to 232 - 1 Unsigned 64-bit integer, u64 0 to 264 - 1 Unsigned 128-bit integer, u128 0 to 2128 - 1 Unsigned 256-bit integer, u256 0 to 2256 - 1","breadcrumbs":"Integers » Integers","id":"11","title":"Integers"},"110":{"body":"A function's body is an expression block. The return value of the function is the last value in the sequence fun example(): u64 { let x = 0; x = x + 1; x // returns 'x'\n} See the section below for more information on returns For more information on expression blocks, see Move variables .","breadcrumbs":"Functions » Function body","id":"110","title":"Function body"},"111":{"body":"Some functions do not have a body specified, and instead have the body provided by the VM. These functions are marked native. Without modifying the VM source code, a programmer cannot add new native functions. Furthermore, it is the intent that native functions are used for either standard library code or for functionality needed for the given Move environment. Most native functions you will likely see are in standard library code such as vector module std::vector { native public fun empty(): vector; ...\n}","breadcrumbs":"Functions » Native Functions","id":"111","title":"Native Functions"},"112":{"body":"When calling a function, the name can be specified either through an alias or fully qualified address 0x42 {\nmodule example { public fun zero(): u64 { 0 }\n}\n} script { use 0x42::example::{Self, zero}; fun call_zero() { // With the `use` above all of these calls are equivalent 0x42::example::zero(); example::zero(); zero(); }\n} When calling a function, an argument must be given for every parameter. address 0x42 {\nmodule example { public fun takes_none(): u64 { 0 } public fun takes_one(x: u64): u64 { x } public fun takes_two(x: u64, y: u64): u64 { x + y } public fun takes_three(x: u64, y: u64, z: u64): u64 { x + y + z }\n}\n} script { use 0x42::example; fun call_all() { example::takes_none(); example::takes_one(0); example::takes_two(0, 1); example::takes_three(0, 1, 2); }\n} Type arguments can be either specified or inferred. Both calls are equivalent. address 0x42 {\nmodule example { public fun id(x: T): T { x }\n}\n} script { use 0x42::example; fun call_all() { example::id(0); example::id(0); }\n} For more details, see Move generics .","breadcrumbs":"Functions » Calling","id":"112","title":"Calling"},"113":{"body":"The result of a function, its \"return value\", is the final value of its function body. For example fun add(x: u64, y: u64): u64 { x + y\n} As mentioned above , the function's body is an expression block . The expression block can sequence various statements, and the final expression in the block will be be the value of that block fun double_and_add(x: u64, y: u64): u64 { let double_x = x * 2; let double_y = y * 2; double_x + double_y\n} The return value here is double_x + double_y","breadcrumbs":"Functions » Returning values","id":"113","title":"Returning values"},"114":{"body":"A function implicitly returns the value that its body evaluates to. However, functions can also use the explicit return expression: fun f1(): u64 { return 0 }\nfun f2(): u64 { 0 } These two functions are equivalent. In this slightly more involved example, the function subtracts two u64 values, but returns early with 0 if the second value is too large: fun safe_sub(x: u64, y: u64): u64 { if (y > x) return 0; x - y\n} Note that the body of this function could also have been written as if (y > x) 0 else x - y. However return really shines is in exiting deep within other control flow constructs. In this example, the function iterates through a vector to find the index of a given value: use std::vector;\nuse std::option::{Self, Option};\nfun index_of(v: &vector, target: &T): Option { let i = 0; let n = vector::length(v); while (i < n) { if (vector::borrow(v, i) == target) return option::some(i); i = i + 1 }; option::none()\n} Using return without an argument is shorthand for return (). That is, the following two functions are equivalent: fun foo() { return }\nfun foo() { return () }","breadcrumbs":"Functions » return expression","id":"114","title":"return expression"},"115":{"body":"Inline functions are functions which are expanded at caller side instead of compiled into Move bytecode. This allows to safe gas and may lead to faster execution. For example, one can define an inline function inline fun percent(x: u64, y: u64):u64 { x * 100 / y } Now, when call percent(2, 200) the compiler will inline the function definition as if the user has written 2 * 100 / 200.","breadcrumbs":"Functions » Inline Functions","id":"115","title":"Inline Functions"},"116":{"body":"Inline functions support function parameters . This allows to define higher-order functions in Move which can comprehend common programming patterns. As inline functions are expanded at compilation time, this feature of function parameters can be supported without direct support for it in Move bytecode. Consider the following function (from the vector module): /// Fold the function over the elements. For example, `fold(vector[1,2,3], 0, f)` will execute\n/// `f(f(f(0, 1), 2), 3)`\npublic inline fun fold( v: vector, init: Accumulator, f: |Accumulator,Element|Accumulator\n): Accumulator { let accu = init; foreach(v, |elem| accu = g(accu, elem)); accu\n} Here, foreach is itself an inline function. In general, only lambda expressions can be passed to function parameters. Similar as the inline function itself, those lambdas are expanded at caller side. Notice that a lambda can access variables in the context, as in the example the variable accu.","breadcrumbs":"Functions » Function Parameters","id":"116","title":"Function Parameters"},"117":{"body":"A struct is a user-defined data structure containing typed fields. Structs can store any non-reference type, including other structs. We often refer to struct values as resources if they cannot be copied and cannot be dropped. In this case, resource values must have ownership transferred by the end of the function. This property makes resources particularly well served for defining global storage schemas or for representing important values (such as a token). By default, structs are linear and ephemeral. By this we mean that they: cannot be copied, cannot be dropped, and cannot be stored in global storage. This means that all values have to have ownership transferred (linear) and the values must be dealt with by the end of the program's execution (ephemeral). We can relax this behavior by giving the struct abilities which allow values to be copied or dropped and also to be stored in global storage or to define global storage schemas.","breadcrumbs":"Structs and Resources » Structs and Resources","id":"117","title":"Structs and Resources"},"118":{"body":"Structs must be defined inside a module: address 0x2 {\nmodule m { struct Foo { x: u64, y: bool } struct Bar {} struct Baz { foo: Foo, } // ^ note: it is fine to have a trailing comma\n}\n} Structs cannot be recursive, so the following definition is invalid: struct Foo { x: Foo }\n// ^ error! Foo cannot contain Foo As mentioned above: by default, a struct declaration is linear and ephemeral. So to allow the value to be used with certain operations (that copy it, drop it, store it in global storage, or use it as a storage schema), structs can be granted abilities by annotating them with has : address 0x2 {\nmodule m { struct Foo has copy, drop { x: u64, y: bool }\n}\n} For more details, see the annotating structs section.","breadcrumbs":"Structs and Resources » Defining Structs","id":"118","title":"Defining Structs"},"119":{"body":"Structs must start with a capital letter A to Z. After the first letter, struct names can contain underscores _, letters a to z, letters A to Z, or digits 0 to 9. struct Foo {}\nstruct BAR {}\nstruct B_a_z_4_2 {} This naming restriction of starting with A to Z is in place to give room for future language features. It may or may not be removed later.","breadcrumbs":"Structs and Resources » Naming","id":"119","title":"Naming"},"12":{"body":"Literal values for these types are specified either as a sequence of digits (e.g.,112) or as hex literals, e.g., 0xFF. The type of the literal can optionally be added as a suffix, e.g., 112u8. If the type is not specified, the compiler will try to infer the type from the context where the literal is used. If the type cannot be inferred, it is assumed to be u64. Number literals can be separated by underscores for grouping and readability. (e.g.,1_234_5678, 1_000u128, 0xAB_CD_12_35). If a literal is too large for its specified (or inferred) size range, an error is reported.","breadcrumbs":"Integers » Literals","id":"12","title":"Literals"},"120":{"body":"","breadcrumbs":"Structs and Resources » Using Structs","id":"120","title":"Using Structs"},"121":{"body":"Values of a struct type can be created (or \"packed\") by indicating the struct name, followed by value for each field: address 0x2 {\nmodule m { struct Foo has drop { x: u64, y: bool } struct Baz has drop { foo: Foo } fun example() { let foo = Foo { x: 0, y: false }; let baz = Baz { foo: foo }; }\n}\n} If you initialize a struct field with a local variable whose name is the same as the field, you can use the following shorthand: let baz = Baz { foo: foo };\n// is equivalent to\nlet baz = Baz { foo }; This is called sometimes called \"field name punning\".","breadcrumbs":"Structs and Resources » Creating Structs","id":"121","title":"Creating Structs"},"122":{"body":"Struct values can be destroyed by binding or assigning them patterns. address 0x2 {\nmodule m { struct Foo { x: u64, y: bool } struct Bar { foo: Foo } struct Baz {} fun example_destroy_foo() { let foo = Foo { x: 3, y: false }; let Foo { x, y: foo_y } = foo; // ^ shorthand for `x: x` // two new bindings // x: u64 = 3 // foo_y: bool = false } fun example_destroy_foo_wildcard() { let foo = Foo { x: 3, y: false }; let Foo { x, y: _ } = foo; // only one new binding since y was bound to a wildcard // x: u64 = 3 } fun example_destroy_foo_assignment() { let x: u64; let y: bool; Foo { x, y } = Foo { x: 3, y: false }; // mutating existing variables x & y // x = 3, y = false } fun example_foo_ref() { let foo = Foo { x: 3, y: false }; let Foo { x, y } = &foo; // two new bindings // x: &u64 // y: &bool } fun example_foo_ref_mut() { let foo = Foo { x: 3, y: false }; let Foo { x, y } = &mut foo; // two new bindings // x: &mut u64 // y: &mut bool } fun example_destroy_bar() { let bar = Bar { foo: Foo { x: 3, y: false } }; let Bar { foo: Foo { x, y } } = bar; // ^ nested pattern // two new bindings // x: u64 = 3 // y: bool = false } fun example_destroy_baz() { let baz = Baz {}; let Baz {} = baz; }\n}\n}","breadcrumbs":"Structs and Resources » Destroying Structs via Pattern Matching","id":"122","title":"Destroying Structs via Pattern Matching"},"123":{"body":"The & and &mut operator can be used to create references to structs or fields. These examples include some optional type annotations (e.g., : &Foo) to demonstrate the type of operations. let foo = Foo { x: 3, y: true };\nlet foo_ref: &Foo = &foo;\nlet y: bool = foo_ref.y; // reading a field via a reference to the struct\nlet x_ref: &u64 = &foo.x; let x_ref_mut: &mut u64 = &mut foo.x;\n*x_ref_mut = 42; // modifying a field via a mutable reference It is possible to borrow inner fields of nested structs: let foo = Foo { x: 3, y: true };\nlet bar = Bar { foo }; let x_ref = &bar.foo.x; You can also borrow a field via a reference to a struct: let foo = Foo { x: 3, y: true };\nlet foo_ref = &foo;\nlet x_ref = &foo_ref.x;\n// this has the same effect as let x_ref = &foo.x","breadcrumbs":"Structs and Resources » Borrowing Structs and Fields","id":"123","title":"Borrowing Structs and Fields"},"124":{"body":"If you need to read and copy a field's value, you can then dereference the borrowed field: let foo = Foo { x: 3, y: true };\nlet bar = Bar { foo: copy foo };\nlet x: u64 = *&foo.x;\nlet y: bool = *&foo.y;\nlet foo2: Foo = *&bar.foo; If the field is implicitly copyable, the dot operator can be used to read fields of a struct without any borrowing. (Only scalar values with the copy ability are implicitly copyable.) let foo = Foo { x: 3, y: true };\nlet x = foo.x; // x == 3\nlet y = foo.y; // y == true Dot operators can be chained to access nested fields: let baz = Baz { foo: Foo { x: 3, y: true } };\nlet x = baz.foo.x; // x = 3; However, this is not permitted for fields that contain non-primitive types, such a vector or another struct: let foo = Foo { x: 3, y: true };\nlet bar = Bar { foo };\nlet foo2: Foo = *&bar.foo;\nlet foo3: Foo = bar.foo; // error! must add an explicit copy with *& The reason behind this design decision is that copying a vector or another struct might be an expensive operation. It is important for a programmer to be aware of this copy and make others aware with the explicit syntax *&. In addition reading from fields, the dot syntax can be used to modify fields, regardless of the field being a primitive type or some other struct. let foo = Foo { x: 3, y: true };\nfoo.x = 42; // foo = Foo { x: 42, y: true }\nfoo.y = !foo.y; // foo = Foo { x: 42, y: false }\nlet bar = Bar { foo }; // bar = Bar { foo: Foo { x: 42, y: false } }\nbar.foo.x = 52; // bar = Bar { foo: Foo { x: 52, y: false } }\nbar.foo = Foo { x: 62, y: true }; // bar = Bar { foo: Foo { x: 62, y: true } } The dot syntax also works via a reference to a struct: let foo = Foo { x: 3, y: true };\nlet foo_ref = &mut foo;\nfoo_ref.x = foo_ref.x + 1;","breadcrumbs":"Structs and Resources » Reading and Writing Fields","id":"124","title":"Reading and Writing Fields"},"125":{"body":"Most struct operations on a struct type T can only be performed inside the module that declares T: Struct types can only be created (\"packed\"), destroyed (\"unpacked\") inside the module that defines the struct. The fields of a struct are only accessible inside the module that defines the struct. Following these rules, if you want to modify your struct outside the module, you will need to provide public APIs for them. The end of the chapter contains some examples of this. However, struct types are always visible to another module or script: // m.move\naddress 0x2 {\nmodule m { struct Foo has drop { x: u64 } public fun new_foo(): Foo { Foo { x: 42 } }\n}\n} // n.move\naddress 0x2 {\nmodule n { use 0x2::m; struct Wrapper has drop { foo: m::Foo } fun f1(foo: m::Foo) { let x = foo.x; // ^ error! cannot access fields of `foo` here } fun f2() { let foo_wrapper = Wrapper { foo: m::new_foo() }; }\n}\n} Note that structs do not have visibility modifiers (e.g., public or private).","breadcrumbs":"Structs and Resources » Privileged Struct Operations","id":"125","title":"Privileged Struct Operations"},"126":{"body":"As mentioned above in Defining Structs , structs are by default linear and ephemeral. This means they cannot be copied or dropped. This property can be very useful when modeling real world resources like money, as you do not want money to be duplicated or get lost in circulation. address 0x2 {\nmodule m { struct Foo { x: u64 } public fun copying_resource() { let foo = Foo { x: 100 }; let foo_copy = copy foo; // error! 'copy'-ing requires the 'copy' ability let foo_ref = &foo; let another_copy = *foo_ref // error! dereference requires the 'copy' ability } public fun destroying_resource1() { let foo = Foo { x: 100 }; // error! when the function returns, foo still contains a value. // This destruction requires the 'drop' ability } public fun destroying_resource2(f: &mut Foo) { *f = Foo { x: 100 } // error! // destroying the old value via a write requires the 'drop' ability }\n}\n} To fix the second example (fun destroying_resource1), you would need to manually \"unpack\" the resource: address 0x2 {\nmodule m { struct Foo { x: u64 } public fun destroying_resource1_fixed() { let foo = Foo { x: 100 }; let Foo { x: _ } = foo; }\n}\n} Recall that you are only able to deconstruct a resource within the module in which it is defined. This can be leveraged to enforce certain invariants in a system, for example, conservation of money. If on the other hand, your struct does not represent something valuable, you can add the abilities copy and drop to get a struct value that might feel more familiar from other programming languages: address 0x2 {\nmodule m { struct Foo has copy, drop { x: u64 } public fun run() { let foo = Foo { x: 100 }; let foo_copy = copy foo; // ^ this code copies foo, whereas `let x = foo` or // `let x = move foo` both move foo let x = foo.x; // x = 100 let x_copy = foo_copy.x; // x = 100 // both foo and foo_copy are implicitly discarded when the function returns }\n}\n}","breadcrumbs":"Structs and Resources » Ownership","id":"126","title":"Ownership"},"127":{"body":"Only structs with the key ability can be saved directly in persistent global storage . All values stored within those key structs must have the store ability. See the ability and global storage chapters for more detail.","breadcrumbs":"Structs and Resources » Storing Resources in Global Storage","id":"127","title":"Storing Resources in Global Storage"},"128":{"body":"Here are two short examples of how you might use structs to represent valuable data (in the case of Coin) or more classical data (in the case of Point and Circle).","breadcrumbs":"Structs and Resources » Examples","id":"128","title":"Examples"},"129":{"body":"address 0x2 {\nmodule m { // We do not want the Coin to be copied because that would be duplicating this \"money\", // so we do not give the struct the 'copy' ability. // Similarly, we do not want programmers to destroy coins, so we do not give the struct the // 'drop' ability. // However, we *want* users of the modules to be able to store this coin in persistent global // storage, so we grant the struct the 'store' ability. This struct will only be inside of // other resources inside of global storage, so we do not give the struct the 'key' ability. struct Coin has store { value: u64, } public fun mint(value: u64): Coin { // You would want to gate this function with some form of access control to prevent // anyone using this module from minting an infinite amount of coins. Coin { value } } public fun withdraw(coin: &mut Coin, amount: u64): Coin { assert!(coin.balance >= amount, 1000); coin.value = coin.value - amount; Coin { value: amount } } public fun deposit(coin: &mut Coin, other: Coin) { let Coin { value } = other; coin.value = coin.value + value; } public fun split(coin: Coin, amount: u64): (Coin, Coin) { let other = withdraw(&mut coin, amount); (coin, other) } public fun merge(coin1: Coin, coin2: Coin): Coin { deposit(&mut coin1, coin2); coin1 } public fun destroy_zero(coin: Coin) { let Coin { value } = coin; assert!(value == 0, 1001); }\n}\n}","breadcrumbs":"Structs and Resources » Example 1: Coin","id":"129","title":"Example 1: Coin"},"13":{"body":"// literals with explicit annotations;\nlet explicit_u8 = 1u8;\nlet explicit_u16 = 1u16;\nlet explicit_u32 = 1u32;\nlet explicit_u64 = 2u64;\nlet explicit_u128 = 3u128;\nlet explicit_u256 = 1u256;\nlet explicit_u64_underscored = 154_322_973u64; // literals with simple inference\nlet simple_u8: u8 = 1;\nlet simple_u16: u16 = 1;\nlet simple_u32: u32 = 1;\nlet simple_u64: u64 = 2;\nlet simple_u128: u128 = 3;\nlet simple_u256: u256 = 1; // literals with more complex inference\nlet complex_u8 = 1; // inferred: u8\n// right hand argument to shift must be u8\nlet _unused = 10 << complex_u8; let x: u8 = 38;\nlet complex_u8 = 2; // inferred: u8\n// arguments to `+` must have the same type\nlet _unused = x + complex_u8; let complex_u128 = 133_876; // inferred: u128\n// inferred from function argument type\nfunction_that_takes_u128(complex_u128); // literals can be written in hex\nlet hex_u8: u8 = 0x1;\nlet hex_u16: u16 = 0x1BAE;\nlet hex_u32: u32 = 0xDEAD80;\nlet hex_u64: u64 = 0xCAFE;\nlet hex_u128: u128 = 0xDEADBEEF;\nlet hex_u256: u256 = 0x1123_456A_BCDE_F;","breadcrumbs":"Integers » Examples","id":"13","title":"Examples"},"130":{"body":"address 0x2 {\nmodule point { struct Point has copy, drop, store { x: u64, y: u64, } public fun new(x: u64, y: u64): Point { Point { x, y } } public fun x(p: &Point): u64 { p.x } public fun y(p: &Point): u64 { p.y } fun abs_sub(a: u64, b: u64): u64 { if (a < b) { b - a } else { a - b } } public fun dist_squared(p1: &Point, p2: &Point): u64 { let dx = abs_sub(p1.x, p2.x); let dy = abs_sub(p1.y, p2.y); dx*dx + dy*dy }\n}\n} address 0x2 {\nmodule circle { use 0x2::point::{Self, Point}; struct Circle has copy, drop, store { center: Point, radius: u64, } public fun new(center: Point, radius: u64): Circle { Circle { center, radius } } public fun overlaps(c1: &Circle, c2: &Circle): bool { let d = point::dist_squared(&c1.center, &c2.center); let r1 = c1.radius; let r2 = c2.radius; d*d <= r1*r1 + 2*r1*r2 + r2*r2 }\n}\n}","breadcrumbs":"Structs and Resources » Example 2: Geometry","id":"130","title":"Example 2: Geometry"},"131":{"body":"Constants are a way of giving a name to shared, static values inside of a module or script. The constant's must be known at compilation. The constant's value is stored in the compiled module or script. And each time the constant is used, a new copy of that value is made.","breadcrumbs":"Constants » Constants","id":"131","title":"Constants"},"132":{"body":"Constant declarations begin with the const keyword, followed by a name, a type, and a value. They can exist in either a script or module const : = ; For example script { const MY_ERROR_CODE: u64 = 0; fun main(input: u64) { assert!(input > 0, MY_ERROR_CODE); } } address 0x42 {\nmodule example { const MY_ADDRESS: address = @0x42; public fun permissioned(s: &signer) { assert!(std::signer::address_of(s) == MY_ADDRESS, 0); } }\n}","breadcrumbs":"Constants » Declaration","id":"132","title":"Declaration"},"133":{"body":"Constants must start with a capital letter A to Z. After the first letter, constant names can contain underscores _, letters a to z, letters A to Z, or digits 0 to 9. const FLAG: bool = false;\nconst MY_ERROR_CODE: u64 = 0;\nconst ADDRESS_42: address = @0x42; Even though you can use letters a to z in a constant. The general style guidelines are to use just uppercase letters A to Z, with underscores _ between each word. This naming restriction of starting with A to Z is in place to give room for future language features. It may or may not be removed later.","breadcrumbs":"Constants » Naming","id":"133","title":"Naming"},"134":{"body":"public constants are not currently supported. const values can be used only in the declaring module.","breadcrumbs":"Constants » Visibility","id":"134","title":"Visibility"},"135":{"body":"Currently, constants are limited to the primitive types bool, u8, u16, u32, u64, u128, u256, address, and vector. Future support for other vector values (besides the \"string\"-style literals) will come later.","breadcrumbs":"Constants » Valid Expressions","id":"135","title":"Valid Expressions"},"136":{"body":"Commonly, consts are assigned a simple value, or literal, of their type. For example const MY_BOOL: bool = false;\nconst MY_ADDRESS: address = @0x70DD;\nconst BYTES: vector = b\"hello world\";\nconst HEX_BYTES: vector = x\"DEADBEEF\";","breadcrumbs":"Constants » Values","id":"136","title":"Values"},"137":{"body":"In addition to literals, constants can include more complex expressions, as long as the compiler is able to reduce the expression to a value at compile time. Currently, equality operations, all boolean operations, all bitwise operations, and all arithmetic operations can be used. const RULE: bool = true && false;\nconst CAP: u64 = 10 * 100 + 1;\nconst SHIFTY: u8 = { (1 << 1) * (1 << 2) * (1 << 3) * (1 << 4)\n};\nconst HALF_MAX: u128 = 340282366920938463463374607431768211455 / 2;\nconst REM: u256 = 57896044618658097711785492504343953926634992332820282019728792003956564819968 % 654321;\nconst EQUAL: bool = 1 == 1; If the operation would result in a runtime exception, the compiler will give an error that it is unable to generate the constant's value const DIV_BY_ZERO: u64 = 1 / 0; // error!\nconst SHIFT_BY_A_LOT: u64 = 1 << 100; // error!\nconst NEGATIVE_U64: u64 = 0 - 1; // error! Note that constants cannot currently refer to other constants. This feature, along with support for other expressions, will be added in the future.","breadcrumbs":"Constants » Complex Expressions","id":"137","title":"Complex Expressions"},"138":{"body":"Generics can be used to define functions and structs over different input data types. This language feature is sometimes referred to as parametric polymorphism . In Move, we will often use the term generics interchangeably with type parameters and type arguments. Generics are commonly used in library code, such as in vector, to declare code that works over any possible instantiation (that satisfies the specified constraints). In other frameworks, generic code can sometimes be used to interact with global storage many different ways that all still share the same implementation.","breadcrumbs":"Generics » Generics","id":"138","title":"Generics"},"139":{"body":"Both functions and structs can take a list of type parameters in their signatures, enclosed by a pair of angle brackets <...>.","breadcrumbs":"Generics » Declaring Type Parameters","id":"139","title":"Declaring Type Parameters"},"14":{"body":"","breadcrumbs":"Integers » Operations","id":"14","title":"Operations"},"140":{"body":"Type parameters for functions are placed after the function name and before the (value) parameter list. The following code defines a generic identity function that takes a value of any type and returns that value unchanged. fun id(x: T): T { // this type annotation is unnecessary but valid (x: T)\n} Once defined, the type parameter T can be used in parameter types, return types, and inside the function body.","breadcrumbs":"Generics » Generic Functions","id":"140","title":"Generic Functions"},"141":{"body":"Type parameters for structs are placed after the struct name, and can be used to name the types of the fields. struct Foo has copy, drop { x: T } struct Bar has copy, drop { x: T1, y: vector,\n} Note that type parameters do not have to be used","breadcrumbs":"Generics » Generic Structs","id":"141","title":"Generic Structs"},"142":{"body":"","breadcrumbs":"Generics » Type Arguments","id":"142","title":"Type Arguments"},"143":{"body":"When calling a generic function, one can specify the type arguments for the function's type parameters in a list enclosed by a pair of angle brackets. fun foo() { let x = id(true);\n} If you do not specify the type arguments, Move's type inference will supply them for you.","breadcrumbs":"Generics » Calling Generic Functions","id":"143","title":"Calling Generic Functions"},"144":{"body":"Similarly, one can attach a list of type arguments for the struct's type parameters when constructing or destructing values of generic types. fun foo() { let foo = Foo { x: true }; let Foo { x } = foo;\n} If you do not specify the type arguments, Move's type inference will supply them for you.","breadcrumbs":"Generics » Using Generic Structs","id":"144","title":"Using Generic Structs"},"145":{"body":"If you specify the type arguments and they conflict with the actual values supplied, an error will be given: fun foo() { let x = id(true); // error! true is not a u64\n} and similarly: fun foo() { let foo = Foo { x: 0 }; // error! 0 is not a bool let Foo { x } = foo; // error! bool is incompatible with address\n}","breadcrumbs":"Generics » Type Argument Mismatch","id":"145","title":"Type Argument Mismatch"},"146":{"body":"In most cases, the Move compiler will be able to infer the type arguments so you don't have to write them down explicitly. Here's what the examples above would look like if we omit the type arguments: fun foo() { let x = id(true); // ^ is inferred let foo = Foo { x: true }; // ^ is inferred let Foo { x } = foo; // ^ is inferred\n} Note: when the compiler is unable to infer the types, you'll need annotate them manually. A common scenario is to call a function with type parameters appearing only at return positions. address 0x2 {\nmodule m { using std::vector; fun foo() { // let v = vector::new(); // ^ The compiler cannot figure out the element type. let v = vector::new(); // ^~~~~ Must annotate manually. }\n}\n} However, the compiler will be able to infer the type if that return value is used later in that function: address 0x2 {\nmodule m { using std::vector; fun foo() { let v = vector::new(); // ^ is inferred vector::push_back(&mut v, 42); }\n}\n}","breadcrumbs":"Generics » Type Inference","id":"146","title":"Type Inference"},"147":{"body":"For a struct definition, an unused type parameter is one that does not appear in any field defined in the struct, but is checked statically at compile time. Move allows unused type parameters so the following struct definition is valid: struct Foo { foo: u64\n} This can be convenient when modeling certain concepts. Here is an example: address 0x2 {\nmodule m { // Currency Specifiers struct Currency1 {} struct Currency2 {} // A generic coin type that can be instantiated using a currency // specifier type. // e.g. Coin, Coin etc. struct Coin has store { value: u64 } // Write code generically about all currencies public fun mint_generic(value: u64): Coin { Coin { value } } // Write code concretely about one currency public fun mint_concrete(value: u64): Coin { Coin { value } }\n}\n} In this example, struct Coin is generic on the Currency type parameter, which specifies the currency of the coin and allows code to be written either generically on any currency or concretely on a specific currency. This genericity applies even when the Currency type parameter does not appear in any of the fields defined in Coin.","breadcrumbs":"Generics » Unused Type Parameters","id":"147","title":"Unused Type Parameters"},"148":{"body":"In the example above, although struct Coin asks for the store ability, neither Coin nor Coin will have the store ability. This is because of the rules for Conditional Abilities and Generic Types and the fact that Currency1 and Currency2 don't have the store ability, despite the fact that they are not even used in the body of struct Coin. This might cause some unpleasant consequences. For example, we are unable to put Coin into a wallet in the global storage. One possible solution would be to add spurious ability annotations to Currency1 and Currency2 (i.e., struct Currency1 has store {}). But, this might lead to bugs or security vulnerabilities because it weakens the types with unnecessary ability declarations. For example, we would never expect a resource in the global storage to have a field in type Currency1, but this would be possible with the spurious store ability. Moreover, the spurious annotations would be infectious, requiring many functions generic on the unused type parameter to also include the necessary constraints. Phantom type parameters solve this problem. Unused type parameters can be marked as phantom type parameters, which do not participate in the ability derivation for structs. In this way, arguments to phantom type parameters are not considered when deriving the abilities for generic types, thus avoiding the need for spurious ability annotations. For this relaxed rule to be sound, Move's type system guarantees that a parameter declared as phantom is either not used at all in the struct definition, or it is only used as an argument to type parameters also declared as phantom. Declaration In a struct definition a type parameter can be declared as phantom by adding the phantom keyword before its declaration. If a type parameter is declared as phantom we say it is a phantom type parameter. When defining a struct, Move's type checker ensures that every phantom type parameter is either not used inside the struct definition or it is only used as an argument to a phantom type parameter. More formally, if a type is used as an argument to a phantom type parameter we say the type appears in phantom position . With this definition in place, the rule for the correct use of phantom parameters can be specified as follows: A phantom type parameter can only appear in phantom position . The following two examples show valid uses of phantom parameters. In the first one, the parameter T1 is not used at all inside the struct definition. In the second one, the parameter T1 is only used as an argument to a phantom type parameter. struct S1 { f: u64 } ^^ Ok: T1 does not appear inside the struct definition struct S2 { f: S1 } ^^ Ok: T1 appears in phantom position The following code shows examples of violations of the rule: struct S1 { f: T } ^ Error: Not a phantom position struct S2 { f: T } struct S3 { f: S2 } ^ Error: Not a phantom position Instantiation When instantiating a struct, the arguments to phantom parameters are excluded when deriving the struct abilities. For example, consider the following code: struct S has copy { f: T1 }\nstruct NoCopy {}\nstruct HasCopy has copy {} Consider now the type S. Since S is defined with copy and all non-phantom arguments have copy then S also has copy. Phantom Type Parameters with Ability Constraints Ability constraints and phantom type parameters are orthogonal features in the sense that phantom parameters can be declared with ability constraints. When instantiating a phantom type parameter with an ability constraint, the type argument has to satisfy that constraint, even though the parameter is phantom. For example, the following definition is perfectly valid: struct S {} The usual restrictions apply and T can only be instantiated with arguments having copy.","breadcrumbs":"Generics » Phantom Type Parameters","id":"148","title":"Phantom Type Parameters"},"149":{"body":"In the examples above, we have demonstrated how one can use type parameters to define \"unknown\" types that can be plugged in by callers at a later time. This however means the type system has little information about the type and has to perform checks in a very conservative way. In some sense, the type system must assume the worst case scenario for an unconstrained generic. Simply put, by default generic type parameters have no abilities . This is where constraints come into play: they offer a way to specify what properties these unknown types have so the type system can allow operations that would otherwise be unsafe.","breadcrumbs":"Generics » Constraints","id":"149","title":"Constraints"},"15":{"body":"Each of these types supports the same set of checked arithmetic operations. For all of these operations, both arguments (the left and right side operands) must be of the same type. If you need to operate over values of different types, you will need to first perform a cast . Similarly, if you expect the result of the operation to be too large for the integer type, perform a cast to a larger size before performing the operation. All arithmetic operations abort instead of behaving in a way that mathematical integers would not (e.g., overflow, underflow, divide-by-zero). Syntax Operation Aborts If + addition Result is too large for the integer type - subtraction Result is less than zero * multiplication Result is too large for the integer type % modular division The divisor is 0 / truncating division The divisor is 0","breadcrumbs":"Integers » Arithmetic","id":"15","title":"Arithmetic"},"150":{"body":"Constraints can be imposed on type parameters using the following syntax. // T is the name of the type parameter\nT: (+ )* The can be any of the four abilities , and a type parameter can be constrained with multiple abilities at once. So all of the following would be valid type parameter declarations: T: copy\nT: copy + drop\nT: copy + drop + store + key","breadcrumbs":"Generics » Declaring Constraints","id":"150","title":"Declaring Constraints"},"151":{"body":"Constraints are checked at call sites so the following code won't compile. struct Foo { x: T } struct Bar { x: Foo }\n// ^ error! u8 does not have 'key' struct Baz { x: Foo }\n// ^ error! T does not have 'key' struct R {} fun unsafe_consume(x: T) { // error! x does not have 'drop'\n} fun consume(x: T) { // valid! // x will be dropped automatically\n} fun foo() { let r = R {}; consume(r); // ^ error! R does not have 'drop'\n} struct R {} fun unsafe_double(x: T) { (copy x, x) // error! x does not have 'copy'\n} fun double(x: T) { (copy x, x) // valid!\n} fun foo(): (R, R) { let r = R {}; double(r) // ^ error! R does not have 'copy'\n} For more information, see the abilities section on conditional abilities and generic types .","breadcrumbs":"Generics » Verifying Constraints","id":"151","title":"Verifying Constraints"},"152":{"body":"","breadcrumbs":"Generics » Limitations on Recursions","id":"152","title":"Limitations on Recursions"},"153":{"body":"Generic structs can not contain fields of the same type, either directly or indirectly, even with different type arguments. All of the following struct definitions are invalid: struct Foo { x: Foo // error! 'Foo' containing 'Foo'\n} struct Bar { x: Bar // error! 'Bar' containing 'Bar'\n} // error! 'A' and 'B' forming a cycle, which is not allowed either.\nstruct A { x: B\n} struct B { x: A y: A\n}","breadcrumbs":"Generics » Recursive Structs","id":"153","title":"Recursive Structs"},"154":{"body":"Move allows generic functions to be called recursively. However, when used in combination with generic structs, this could create an infinite number of types in certain cases, and allowing this means adding unnecessary complexity to the compiler, vm and other language components. Therefore, such recursions are forbidden. Allowed: address 0x2 {\nmodule m { struct A {} // Finitely many types -- allowed. // foo -> foo -> foo -> ... is valid fun foo() { foo(); } // Finitely many types -- allowed. // foo -> foo> -> foo> -> ... is valid fun foo() { foo>(); }\n}\n} Not allowed: address 0x2 {\nmodule m { struct A {} // Infinitely many types -- NOT allowed. // error! // foo -> foo> -> foo>> -> ... fun foo() { foo>(); }\n}\n} address 0x2 {\nmodule n { struct A {} // Infinitely many types -- NOT allowed. // error! // foo -> bar -> foo> // -> bar, T2> -> foo, A> // -> bar, A> -> foo, A>> // -> ... fun foo() { bar(); } fun bar { foo>(); }\n}\n} Note, the check for type level recursions is based on a conservative analysis on the call sites and does NOT take control flow or runtime values into account. address 0x2 {\nmodule m { struct A {} fun foo(n: u64) { if (n > 0) { foo>(n - 1); }; }\n}\n} The function in the example above will technically terminate for any given input and therefore only creating finitely many types, but it is still considered invalid by Move's type system.","breadcrumbs":"Generics » Advanced Topic: Type-level Recursions","id":"154","title":"Advanced Topic: Type-level Recursions"},"155":{"body":"Abilities are a typing feature in Move that control what actions are permissible for values of a given type. This system grants fine grained control over the \"linear\" typing behavior of values, as well as if and how values are used in global storage. This is implemented by gating access to certain bytecode instructions so that for a value to be used with the bytecode instruction, it must have the ability required (if one is required at all—not every instruction is gated by an ability).","breadcrumbs":"Type Abilities » Abilities","id":"155","title":"Abilities"},"156":{"body":"The four abilities are: copy Allows values of types with this ability to be copied. drop Allows values of types with this ability to be popped/dropped. store Allows values of types with this ability to exist inside a struct in global storage. key Allows the type to serve as a key for global storage operations.","breadcrumbs":"Type Abilities » The Four Abilities","id":"156","title":"The Four Abilities"},"157":{"body":"The copy ability allows values of types with that ability to be copied. It gates the ability to copy values out of local variables with the copy operator and to copy values via references with dereference *e . If a value has copy, all values contained inside of that value have copy.","breadcrumbs":"Type Abilities » copy","id":"157","title":"copy"},"158":{"body":"The drop ability allows values of types with that ability to be dropped. By dropped, we mean that value is not transferred and is effectively destroyed as the Move program executes. As such, this ability gates the ability to ignore values in a multitude of locations, including: not using the value in a local variable or parameter not using the value in a sequence via ; overwriting values in variables in assignments overwriting values via references when writing *e1 = e2 . If a value has drop, all values contained inside of that value have drop.","breadcrumbs":"Type Abilities » drop","id":"158","title":"drop"},"159":{"body":"The store ability allows values of types with this ability to exist inside of a struct (resource) in global storage, but not necessarily as a top-level resource in global storage. This is the only ability that does not directly gate an operation. Instead it gates the existence in global storage when used in tandem with key. If a value has store, all values contained inside of that value have store","breadcrumbs":"Type Abilities » store","id":"159","title":"store"},"16":{"body":"The integer types support the following bitwise operations that treat each number as a series of individual bits, either 0 or 1, instead of as numerical integer values. Bitwise operations do not abort. Syntax Operation Description & bitwise and Performs a boolean and for each bit pairwise | bitwise or Performs a boolean or for each bit pairwise ^ bitwise xor Performs a boolean exclusive or for each bit pairwise","breadcrumbs":"Integers » Bitwise","id":"16","title":"Bitwise"},"160":{"body":"The key ability allows the type to serve as a key for global storage operations . It gates all global storage operations, so in order for a type to be used with move_to, borrow_global, move_from, etc., the type must have the key ability. Note that the operations still must be used in the module where the key type is defined (in a sense, the operations are private to the defining module). If a value has key, all values contained inside of that value have store. This is the only ability with this sort of asymmetry.","breadcrumbs":"Type Abilities » key","id":"160","title":"key"},"161":{"body":"Most primitive, builtin types have copy, drop, and store with the exception of signer, which just has drop bool, u8, u16, u32, u64, u128, u256, and address all have copy, drop, and store. signer has drop Cannot be copied and cannot be put into global storage vector may have copy, drop, and store depending on the abilities of T. See Conditional Abilities and Generic Types for more details. Immutable references & and mutable references &mut both have copy and drop. This refers to copying and dropping the reference itself, not what they refer to. References cannot appear in global storage, hence they do not have store. None of the primitive types have key, meaning none of them can be used directly with the global storage operations .","breadcrumbs":"Type Abilities » Builtin Types","id":"161","title":"Builtin Types"},"162":{"body":"To declare that a struct has an ability, it is declared with has after the struct name but before the fields. For example: struct Ignorable has drop { f: u64 }\nstruct Pair has copy, drop, store { x: u64, y: u64 } In this case: Ignorable has the drop ability. Pair has copy, drop, and store. All of these abilities have strong guarantees over these gated operations. The operation can be performed on the value only if it has that ability; even if the value is deeply nested inside of some other collection! As such: when declaring a struct’s abilities, certain requirements are placed on the fields. All fields must satisfy these constraints. These rules are necessary so that structs satisfy the reachability rules for the abilities given above. If a struct is declared with the ability... copy, all fields must have copy. drop, all fields must have drop. store, all fields must have store. key, all fields must have store. key is the only ability currently that doesn’t require itself. For example: // A struct without any abilities\nstruct NoAbilities {} struct WantsCopy has copy { f: NoAbilities, // ERROR 'NoAbilities' does not have 'copy'\n} and similarly: // A struct without any abilities\nstruct NoAbilities {} struct MyResource has key { f: NoAbilities, // Error 'NoAbilities' does not have 'store'\n}","breadcrumbs":"Type Abilities » Annotating Structs","id":"162","title":"Annotating Structs"},"163":{"body":"When abilities are annotated on a generic type, not all instances of that type are guaranteed to have that ability. Consider this struct declaration: struct Cup has copy, drop, store, key { item: T } It might be very helpful if Cup could hold any type, regardless of its abilities. The type system can see the type parameter, so it should be able to remove abilities from Cup if it sees a type parameter that would violate the guarantees for that ability. This behavior might sound a bit confusing at first, but it might be more understandable if we think about collection types. We could consider the builtin type vector to have the following type declaration: vector has copy, drop, store; We want vectors to work with any type. We don't want separate vector types for different abilities. So what are the rules we would want? Precisely the same that we would want with the field rules above. So, it would be safe to copy a vector value only if the inner elements can be copied. It would be safe to ignore a vector value only if the inner elements can be ignored/dropped. And, it would be safe to put a vector in global storage only if the inner elements can be in global storage. To have this extra expressiveness, a type might not have all the abilities it was declared with depending on the instantiation of that type; instead, the abilities a type will have depends on both its declaration and its type arguments. For any type, type parameters are pessimistically assumed to be used inside of the struct, so the abilities are only granted if the type parameters meet the requirements described above for fields. Taking Cup from above as an example: Cup has the ability copy only if T has copy. It has drop only if T has drop. It has store only if T has store. It has key only if T has store. Here are examples for this conditional system for each ability:","breadcrumbs":"Type Abilities » Conditional Abilities and Generic Types","id":"163","title":"Conditional Abilities and Generic Types"},"164":{"body":"struct NoAbilities {}\nstruct S has copy, drop { f: bool }\nstruct Cup has copy, drop, store { item: T } fun example(c_x: Cup, c_s: Cup) { // Valid, 'Cup' has 'copy' because 'u64' has 'copy' let c_x2 = copy c_x; // Valid, 'Cup' has 'copy' because 'S' has 'copy' let c_s2 = copy c_s;\n} fun invalid(c_account: Cup, c_n: Cup) { // Invalid, 'Cup' does not have 'copy'. // Even though 'Cup' was declared with copy, the instance does not have 'copy' // because 'signer' does not have 'copy' let c_account2 = copy c_account; // Invalid, 'Cup' does not have 'copy' // because 'NoAbilities' does not have 'copy' let c_n2 = copy c_n;\n}","breadcrumbs":"Type Abilities » Example: conditional copy","id":"164","title":"Example: conditional copy"},"165":{"body":"struct NoAbilities {}\nstruct S has copy, drop { f: bool }\nstruct Cup has copy, drop, store { item: T } fun unused() { Cup { item: true }; // Valid, 'Cup' has 'drop' Cup { item: S { f: false }}; // Valid, 'Cup' has 'drop'\n} fun left_in_local(c_account: Cup): u64 { let c_b = Cup { item: true }; let c_s = Cup { item: S { f: false }}; // Valid return: 'c_account', 'c_b', and 'c_s' have values // but 'Cup', 'Cup', and 'Cup' have 'drop' 0\n} fun invalid_unused() { // Invalid, Cannot ignore 'Cup' because it does not have 'drop'. // Even though 'Cup' was declared with 'drop', the instance does not have 'drop' // because 'NoAbilities' does not have 'drop' Cup { item: NoAbilities {}};\n} fun invalid_left_in_local(): u64 { let n = Cup { item: NoAbilities {}}; // Invalid return: 'c_n' has a value // and 'Cup' does not have 'drop' 0\n}","breadcrumbs":"Type Abilities » Example: conditional drop","id":"165","title":"Example: conditional drop"},"166":{"body":"struct Cup has copy, drop, store { item: T } // 'MyInnerResource' is declared with 'store' so all fields need 'store'\nstruct MyInnerResource has store { yes: Cup, // Valid, 'Cup' has 'store' // no: Cup, Invalid, 'Cup' does not have 'store'\n} // 'MyResource' is declared with 'key' so all fields need 'store'\nstruct MyResource has key { yes: Cup, // Valid, 'Cup' has 'store' inner: Cup, // Valid, 'Cup' has 'store' // no: Cup, Invalid, 'Cup' does not have 'store'\n}","breadcrumbs":"Type Abilities » Example: conditional store","id":"166","title":"Example: conditional store"},"167":{"body":"struct NoAbilities {}\nstruct MyResource has key { f: T } fun valid(account: &signer) acquires MyResource { let addr = signer::address_of(account); // Valid, 'MyResource' has 'key' let has_resource = exists>(addr); if (!has_resource) { // Valid, 'MyResource' has 'key' move_to(account, MyResource { f: 0 }) }; // Valid, 'MyResource' has 'key' let r = borrow_global_mut>(addr) r.f = r.f + 1;\n} fun invalid(account: &signer) { // Invalid, 'MyResource' does not have 'key' let has_it = exists>(addr); // Invalid, 'MyResource' does not have 'key' let NoAbilities {} = move_from(addr); // Invalid, 'MyResource' does not have 'key' move_to(account, NoAbilities {}); // Invalid, 'MyResource' does not have 'key' borrow_global(addr);\n}","breadcrumbs":"Type Abilities » Example: conditional key","id":"167","title":"Example: conditional key"},"168":{"body":"The use syntax can be used to create aliases to members in other modules. use can be used to create aliases that last either for the entire module, or for a given expression block scope.","breadcrumbs":"Uses and Aliases » Uses and Aliases","id":"168","title":"Uses and Aliases"},"169":{"body":"There are several different syntax cases for use. Starting with the most simple, we have the following for creating aliases to other modules use ::;\nuse :: as ; For example use std::vector;\nuse std::vector as V; use std::vector; introduces an alias vector for std::vector. This means that anywhere you would want to use the module name std::vector (assuming this use is in scope), you could use vector instead. use std::vector; is equivalent to use std::vector as vector; Similarly use std::vector as V; would let you use V instead of std::vector use std::vector;\nuse std::vector as V; fun new_vecs(): (vector, vector, vector) { let v1 = std::vector::empty(); let v2 = vector::empty(); let v3 = V::empty(); (v1, v2, v3)\n} If you want to import a specific module member (such as a function, struct, or constant). You can use the following syntax. use ::::;\nuse :::: as ; For example use std::vector::empty;\nuse std::vector::empty as empty_vec; This would let you use the function std::vector::empty without full qualification. Instead you could use empty and empty_vec respectively. Again, use std::vector::empty; is equivalent to use std::vector::empty as empty; use std::vector::empty;\nuse std::vector::empty as empty_vec; fun new_vecs(): (vector, vector, vector) { let v1 = std::vector::empty(); let v2 = empty(); let v3 = empty_vec(); (v1, v2, v3)\n} If you want to add aliases for multiple module members at once, you can do so with the following syntax use ::::{, as ... }; For example use std::vector::{push_back, length as len, pop_back}; fun swap_last_two(v: &mut vector) { assert!(len(v) >= 2, 42); let last = pop_back(v); let second_to_last = pop_back(v); push_back(v, last); push_back(v, second_to_last)\n} If you need to add an alias to the Module itself in addition to module members, you can do that in a single use using Self. Self is a member of sorts that refers to the module. use std::vector::{Self, empty}; For clarity, all of the following are equivalent: use std::vector;\nuse std::vector as vector;\nuse std::vector::Self;\nuse std::vector::Self as vector;\nuse std::vector::{Self};\nuse std::vector::{Self as vector}; If needed, you can have as many aliases for any item as you like use std::vector::{ Self, Self as V, length, length as len,\n}; fun pop_twice(v: &mut vector): (T, T) { // all options available given the `use` above assert!(vector::length(v) > 1, 42); assert!(V::length(v) > 1, 42); assert!(length(v) > 1, 42); assert!(len(v) > 1, 42); (vector::pop_back(v), vector::pop_back(v))\n}","breadcrumbs":"Uses and Aliases » Syntax","id":"169","title":"Syntax"},"17":{"body":"Similar to the bitwise operations, each integer type supports bit shifts. But unlike the other operations, the righthand side operand (how many bits to shift by) must always be a u8 and need not match the left side operand (the number you are shifting). Bit shifts can abort if the number of bits to shift by is greater than or equal to 8, 16, 32, 64, 128 or 256 for u8, u16, u32, u64, u128 and u256 respectively. Syntax Operation Aborts if << shift left Number of bits to shift by is greater than the size of the integer type >> shift right Number of bits to shift by is greater than the size of the integer type","breadcrumbs":"Integers » Bit Shifts","id":"17","title":"Bit Shifts"},"170":{"body":"Inside of a module all use declarations are usable regardless of the order of declaration. address 0x42 {\nmodule example { use std::vector; fun example(): vector { let v = empty(); vector::push_back(&mut v, 0); vector::push_back(&mut v, 10); v } use std::vector::empty;\n}\n} The aliases declared by use in the module usable within that module. Additionally, the aliases introduced cannot conflict with other module members. See Uniqueness for more details","breadcrumbs":"Uses and Aliases » Inside a module","id":"170","title":"Inside a module"},"171":{"body":"You can add use declarations to the beginning of any expression block address 0x42 {\nmodule example { fun example(): vector { use std::vector::{empty, push_back}; let v = empty(); push_back(&mut v, 0); push_back(&mut v, 10); v }\n}\n} As with let, the aliases introduced by use in an expression block are removed at the end of that block. address 0x42 {\nmodule example { fun example(): vector { let result = { use std::vector::{empty, push_back}; let v = empty(); push_back(&mut v, 0); push_back(&mut v, 10); v }; result } }\n} Attempting to use the alias after the block ends will result in an error fun example(): vector { let result = { use std::vector::{empty, push_back}; let v = empty(); push_back(&mut v, 0); push_back(&mut v, 10); v }; let v2 = empty(); // ERROR!\n// ^^^^^ unbound function 'empty' result\n} Any use must be the first item in the block. If the use comes after any expression or let, it will result in a parsing error { let x = 0; use std::vector; // ERROR! let v = vector::empty();\n}","breadcrumbs":"Uses and Aliases » Inside an expression","id":"171","title":"Inside an expression"},"172":{"body":"Aliases must follow the same rules as other module members. This means that aliases to structs or constants must start with A to Z address 0x42 {\nmodule data { struct S {} const FLAG: bool = false; fun foo() {}\n}\nmodule example { use 0x42::data::{ S as s, // ERROR! FLAG as fLAG, // ERROR! foo as FOO, // valid foo as bar, // valid };\n}\n}","breadcrumbs":"Uses and Aliases » Naming rules","id":"172","title":"Naming rules"},"173":{"body":"Inside a given scope, all aliases introduced by use declarations must be unique. For a module, this means aliases introduced by use cannot overlap address 0x42 {\nmodule example { use std::vector::{empty as foo, length as foo}; // ERROR! // ^^^ duplicate 'foo' use std::vector::empty as bar; use std::vector::length as bar; // ERROR! // ^^^ duplicate 'bar' }\n} And, they cannot overlap with any of the module's other members address 0x42 {\nmodule data { struct S {}\n}\nmodule example { use 0x42::data::S; struct S { value: u64 } // ERROR! // ^ conflicts with alias 'S' above\n}\n} Inside of an expression block, they cannot overlap with each other, but they can shadow other aliases or names from an outer scope","breadcrumbs":"Uses and Aliases » Uniqueness","id":"173","title":"Uniqueness"},"174":{"body":"use aliases inside of an expression block can shadow names (module members or aliases) from the outer scope. As with shadowing of locals, the shadowing ends at the end of the expression block; address 0x42 {\nmodule example { struct WrappedVector { vec: vector } fun empty(): WrappedVector { WrappedVector { vec: std::vector::empty() } } fun example1(): (WrappedVector, WrappedVector) { let vec = { use std::vector::{empty, push_back}; // 'empty' now refers to std::vector::empty let v = empty(); push_back(&mut v, 0); push_back(&mut v, 1); push_back(&mut v, 10); v }; // 'empty' now refers to Self::empty (empty(), WrappedVector { vec }) } fun example2(): (WrappedVector, WrappedVector) { use std::vector::{empty, push_back}; let w: WrappedVector = { use 0x42::example::empty; empty() }; push_back(&mut w.vec, 0); push_back(&mut w.vec, 1); push_back(&mut w.vec, 10); let vec = empty(); push_back(&mut vec, 0); push_back(&mut vec, 1); push_back(&mut vec, 10); (w, WrappedVector { vec }) }\n}\n}","breadcrumbs":"Uses and Aliases » Shadowing","id":"174","title":"Shadowing"},"175":{"body":"An unused use will result in an error address 0x42 {\nmodule example { use std::vector::{empty, push_back}; // ERROR! // ^^^^^^^^^ unused alias 'push_back' fun example(): vector { empty() }\n}\n}","breadcrumbs":"Uses and Aliases » Unused Use or Alias","id":"175","title":"Unused Use or Alias"},"176":{"body":"The friend syntax is used to declare modules that are trusted by the current module. A trusted module is allowed to call any function defined in the current module that have the public(friend) visibility. For details on function visibilities, please refer to the Visibility section in Functions .","breadcrumbs":"Friends » Friends","id":"176","title":"Friends"},"177":{"body":"A module can declare other modules as friends via friend declaration statements, in the format of friend — friend declaration using fully qualified module name like the example below, or address 0x42 {\nmodule a { friend 0x42::b;\n}\n} friend — friend declaration using a module name alias, where the module alias is introduced via the use statement. address 0x42 {\nmodule a { use 0x42::b; friend b;\n}\n} A module may have multiple friend declarations, and the union of all the friend modules forms the friend list. In the example below, both 0x42::B and 0x42::C are considered as friends of 0x42::A. address 0x42 {\nmodule a { friend 0x42::b; friend 0x42::c;\n}\n} Unlike use statements, friend can only be declared in the module scope and not in the expression block scope. friend declarations may be located anywhere a top-level construct (e.g., use, function, struct, etc.) is allowed. However, for readability, it is advised to place friend declarations near the beginning of the module definition. Note that the concept of friendship does not apply to Move scripts: A Move script cannot declare friend modules as doing so is considered meaningless: there is no mechanism to call the function defined in a script. A Move module cannot declare friend scripts as well because scripts are ephemeral code snippets that are never published to global storage.","breadcrumbs":"Friends » Friend declaration","id":"177","title":"Friend declaration"},"178":{"body":"Friend declarations are subject to the following rules: A module cannot declare itself as a friend. address 0x42 {\nmodule m { friend Self; // ERROR! }\n// ^^^^ Cannot declare the module itself as a friend\n} address 0x43 {\nmodule m { friend 0x43::M; // ERROR! }\n// ^^^^^^^ Cannot declare the module itself as a friend\n} Friend modules must be known by the compiler address 0x42 {\nmodule m { friend 0x42::nonexistent; // ERROR! }\n// ^^^^^^^^^^^^^^^^^ Unbound module '0x42::nonexistent'\n} Friend modules must be within the same account address. (Note: this is not a technical requirement but rather a policy decision which may be relaxed later.) address 0x42 {\nmodule m {}\n} address 0x43 {\nmodule n { friend 0x42::m; // ERROR! }\n// ^^^^^^^ Cannot declare modules out of the current address as a friend\n} Friends relationships cannot create cyclic module dependencies. Cycles are not allowed in the friend relationships, e.g., the relation 0x2::a friends 0x2::b friends 0x2::c friends 0x2::a is not allowed. More generally, declaring a friend module adds a dependency upon the current module to the friend module (because the purpose is for the friend to call functions in the current module). If that friend module is already used, either directly or transitively, a cycle of dependencies would be created. address 0x2 {\nmodule a { use 0x2::c; friend 0x2::b; public fun a() { c::c() }\n} module b { friend 0x2::c; // ERROR!\n// ^^^^^^ This friend relationship creates a dependency cycle: '0x2::b' is a friend of '0x2::a' uses '0x2::c' is a friend of '0x2::b'\n} module c { public fun c() {}\n}\n} The friend list for a module cannot contain duplicates. address 0x42 {\nmodule a {} module m { use 0x42::a as aliased_a; friend 0x42::A; friend aliased_a; // ERROR!\n// ^^^^^^^^^ Duplicate friend declaration '0x42::a'. Friend declarations in a module must be unique\n}\n}","breadcrumbs":"Friends » Friend declaration rules","id":"178","title":"Friend declaration rules"},"179":{"body":"Packages allow Move programmers to more easily re-use code and share it across projects. The Move package system allows programmers to easily: Define a package containing Move code; Parameterize a package by named addresses ; Import and use packages in other Move code and instantiate named addresses; Build packages and generate associated compilation artifacts from packages; and Work with a common interface around compiled Move artifacts.","breadcrumbs":"Packages » Packages","id":"179","title":"Packages"},"18":{"body":"Integer types are the only types in Move that can use the comparison operators. Both arguments need to be of the same type. If you need to compare integers of different types, you will need to cast one of them first. Comparison operations do not abort. Syntax Operation < less than > greater than <= less than or equal to >= greater than or equal to","breadcrumbs":"Integers » Comparisons","id":"18","title":"Comparisons"},"180":{"body":"A Move package source directory contains a Move.toml package manifest file along with a set of subdirectories: a_move_package\n├── Move.toml (required)\n├── sources (required)\n├── examples (optional, test & dev mode)\n├── scripts (optional)\n├── doc_templates (optional)\n└── tests (optional, test mode) The directories marked required must be present in order for the directory to be considered a Move package and to be compiled. Optional directories can be present, and if so will be included in the compilation process. Depending on the mode that the package is built with (test or dev), the tests and examples directories will be included as well. The sources directory can contain both Move modules and Move scripts (both transaction scripts and modules containing script functions). The examples directory can hold additional code to be used only for development and/or tutorial purposes that will not be included when compiled outside test or dev mode. A scripts directory is supported so transaction scripts can be separated from modules if that is desired by the package author. The scripts directory will always be included for compilation if it is present. Documentation will be built using any documentation templates present in the doc_templates directory.","breadcrumbs":"Packages » Package Layout and Manifest Syntax","id":"180","title":"Package Layout and Manifest Syntax"},"181":{"body":"The Move package manifest is defined within the Move.toml file and has the following syntax. Optional fields are marked with *, + denotes one or more elements: [package]\nname = # e.g., \"MoveStdlib\"\nversion = \"..\" # e.g., \"0.1.1\"\nlicense* = # e.g., \"MIT\", \"GPL\", \"Apache 2.0\"\nauthors* = [