diff --git a/move-basics/ownership-and-scope.html b/move-basics/ownership-and-scope.html index 4766831..f1b1995 100644 --- a/move-basics/ownership-and-scope.html +++ b/move-basics/ownership-and-scope.html @@ -205,10 +205,15 @@
init
init
, be private and have no return values.TxContext
always being the last argument.
fun init(ctx: &mut TxContext) { /* ... */}
fun init(otw: OTW, ctx: &mut TxContext) { /* ... */ }
@@ -5711,7 +5716,7 @@ Witness in Mo
}
}
-The instance of the struct W
is passed into the new
function to create an Instance<W>
, thereby
+
The instance of the struct W
is passed into the new_instance
function to create an Instance<W>
, thereby
proving that the module book::witness_source
owns the type W
.
Witness allows generic types to be instantiated with a concrete type. This is useful for inheriting @@ -5987,7 +5992,7 @@
admin_function
is not very explicit, can be
+safety and expressiveness. The signature for the admin_action
is not very explicit, can be
called by anyone else. And due to Publisher
object being standard, there now is a risk of
unauthorized access if the from_module
check is not performed. So it's important to be cautious
when using the Publisher
object as an admin role.
@@ -6383,7 +6388,7 @@ init
init
, be private and have no return values.TxContext
always being the last argument.
fun init(ctx: &mut TxContext) { /* ... */}
fun init(otw: OTW, ctx: &mut TxContext) { /* ... */ }
diff --git a/programmability/publisher.html b/programmability/publisher.html
index ef654e0..b63e633 100644
--- a/programmability/publisher.html
+++ b/programmability/publisher.html
@@ -248,7 +248,7 @@ Capabilities, such as type
-safety and expressiveness. The signature for the admin_function
is not very explicit, can be
+safety and expressiveness. The signature for the admin_action
is not very explicit, can be
called by anyone else. And due to Publisher
object being standard, there now is a risk of
unauthorized access if the from_module
check is not performed. So it's important to be cautious
when using the Publisher
object as an admin role.
diff --git a/programmability/witness-pattern.html b/programmability/witness-pattern.html
index 5a8fa96..1b617de 100644
--- a/programmability/witness-pattern.html
+++ b/programmability/witness-pattern.html
@@ -225,7 +225,7 @@ Witness in Mo
}
}
-The instance of the struct W
is passed into the new
function to create an Instance<W>
, thereby
+
The instance of the struct W
is passed into the new_instance
function to create an Instance<W>
, thereby
proving that the module book::witness_source
owns the type W
.
Witness allows generic types to be instantiated with a concrete type. This is useful for inheriting diff --git a/reference/print.html b/reference/print.html index f34f1b5..7f111bd 100644 --- a/reference/print.html +++ b/reference/print.html @@ -1094,7 +1094,7 @@
let
can also introduce more than one local at a time when destructuring (or matching against) a
+
let
can also introduce more than one local variables at a time when destructuring (or matching against) a
struct. In this form, the let
creates a set of local variables that are initialized to the values
of the fields from a struct. The syntax looks like this:
public struct T { f1: u64, f2: u64 }
@@ -1107,7 +1107,7 @@ public struct P(u64, u64)
and
-let P(local1, local2) = T { f1: 1, f2: 2 };
+let P (local1, local2) = P ( 1, 2 );
// local1: u64
// local2: u64
diff --git a/reference/searchindex.js b/reference/searchindex.js
index 7b1422a..1fd36db 100644
--- a/reference/searchindex.js
+++ b/reference/searchindex.js
@@ -1 +1 @@
-Object.assign(window.search, {"doc_urls":["introduction.html#the-move-reference","modules.html#modules","modules.html#syntax","modules.html#names","modules.html#members","primitive-types.html#primitive-types","primitive-types/integers.html#integers","primitive-types/integers.html#literals","primitive-types/integers.html#examples","primitive-types/integers.html#operations","primitive-types/integers.html#arithmetic","primitive-types/integers.html#bitwise","primitive-types/integers.html#bit-shifts","primitive-types/integers.html#comparisons","primitive-types/integers.html#equality","primitive-types/integers.html#casting","primitive-types/integers.html#ownership","primitive-types/bool.html#bool","primitive-types/bool.html#literals","primitive-types/bool.html#operations","primitive-types/bool.html#logical","primitive-types/bool.html#control-flow","primitive-types/bool.html#ownership","primitive-types/address.html#address","primitive-types/address.html#addresses-and-their-syntax","primitive-types/address.html#named-addresses","primitive-types/address.html#examples","primitive-types/vector.html#vector","primitive-types/vector.html#literals","primitive-types/vector.html#general-vector-literals","primitive-types/vector.html#vector-literals","primitive-types/vector.html#operations","primitive-types/vector.html#example","primitive-types/vector.html#destroying-and-copying-vectors","primitive-types/vector.html#ownership","primitive-types/references.html#references","primitive-types/references.html#reference-operators","primitive-types/references.html#reading-and-writing-through-references","primitive-types/references.html#freeze-inference","primitive-types/references.html#subtyping","primitive-types/references.html#ownership","primitive-types/references.html#references-cannot-be-stored","primitive-types/tuples.html#tuples-and-unit","primitive-types/tuples.html#literals","primitive-types/tuples.html#examples","primitive-types/tuples.html#operations","primitive-types/tuples.html#destructuring","primitive-types/tuples.html#subtyping","primitive-types/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#automatic-borrowing","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","control-flow.html#control-flow","control-flow/conditionals.html#conditional-if-expressions","control-flow/conditionals.html#grammar-for-conditionals","control-flow/loops.html#loop-constructs-in-move","control-flow/loops.html#while-loops","control-flow/loops.html#using-break-inside-of-while-loops","control-flow/loops.html#using-continue-inside-of-while-loops","control-flow/loops.html#loop-expressions","control-flow/loops.html#using-break-with-values-in-loop","control-flow/loops.html#using-continue-inside-of-loop-expressions","control-flow/loops.html#the-type-of-while-and-loop","control-flow/labeled-control-flow.html#labeled-control-flow","control-flow/pattern-matching.html#pattern-matching","control-flow/pattern-matching.html#match-syntax","control-flow/pattern-matching.html#pattern-syntax","control-flow/pattern-matching.html#patterns-and-variables","control-flow/pattern-matching.html#combining-patterns","control-flow/pattern-matching.html#restrictions-on-some-patterns","control-flow/pattern-matching.html#pattern-typing","control-flow/pattern-matching.html#matching","control-flow/pattern-matching.html#matching-constructors","control-flow/pattern-matching.html#ability-constraints","control-flow/pattern-matching.html#exhaustiveness","control-flow/pattern-matching.html#guards","control-flow/pattern-matching.html#limitations-on-specific-patterns","control-flow/pattern-matching.html#mutability-usage","control-flow/pattern-matching.html#-usage","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#return-type","functions.html#function-body","functions.html#native-functions","functions.html#calling","functions.html#returning-values","functions.html#return-expression","structs.html#structs-and-resources","structs.html#defining-structs","structs.html#visibility","structs.html#abilities","structs.html#naming","structs.html#using-structs","structs.html#creating-structs","structs.html#destroying-structs-via-pattern-matching","structs.html#accessing-struct-fields","structs.html#borrowing-structs-and-fields","structs.html#reading-and-writing-fields","structs.html#privileged-struct-operations","structs.html#ownership","structs.html#storage","enums.html#enumerations","enums.html#defining-enums","enums.html#visibility","enums.html#abilities","enums.html#naming","enums.html#using-enums","enums.html#creating-enum-variants","enums.html#pattern-matching-enum-variants-and-destructuring","enums.html#overwriting-to-enum-values","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#integers","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-and-enums","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#multiple-aliases","uses.html#self-aliases","uses.html#multiple-aliases-for-the-same-definition","uses.html#nested-imports","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","method-syntax.html#methods","method-syntax.html#syntax","method-syntax.html#method-resolution","method-syntax.html#functions-in-the-defining-module","method-syntax.html#use-fun-aliases","method-syntax.html#public-use-fun-aliases","method-syntax.html#interactions-with-use-aliases","method-syntax.html#scoping","method-syntax.html#automatic-borrowing","method-syntax.html#chaining","index-syntax.html#index-syntax","index-syntax.html#overview-and-summary","index-syntax.html#usage","index-syntax.html#index-functions-take-flexible-arguments","index-syntax.html#defining-index-syntax-functions","index-syntax.html#declaration","index-syntax.html#type-constraints","index-syntax.html#type-compatibility","packages.html#packages","packages.html#package-layout-and-manifest-syntax","packages.html#movetoml","packages.html#named-addresses-during-compilation","packages.html#declaring-named-addresses","packages.html#scope-and-renaming-of-named-addresses","packages.html#instantiating-named-addresses","packages.html#usage-and-artifacts","packages.html#artifacts","packages.html#movelock","packages.html#the-move-section","packages.html#the-movepackage-sections","packages.html#the-movetoolchain-version-section","unit-testing.html#unit-tests","unit-testing.html#test-annotations","unit-testing.html#expected-failures","unit-testing.html#1-expected_failureabort_code--","unit-testing.html#2-expected_failurearithmetic_error-location--","unit-testing.html#3-expected_failureout_of_gas-location--","unit-testing.html#4-expected_failurevector_error-minor_status---location--","unit-testing.html#5-expected_failure","unit-testing.html#test-only-annotations","unit-testing.html#running-unit-tests","unit-testing.html#example","unit-testing.html#running-tests","unit-testing.html#using-test-flags","coding-conventions.html","friends.html#deprecated-friends","friends.html#friend-declaration","friends.html#friend-declaration-rules"],"index":{"documentStore":{"docInfo":{"0":{"body":61,"breadcrumbs":4,"title":2},"1":{"body":52,"breadcrumbs":2,"title":1},"10":{"body":79,"breadcrumbs":4,"title":1},"100":{"body":89,"breadcrumbs":6,"title":2},"101":{"body":209,"breadcrumbs":5,"title":1},"102":{"body":148,"breadcrumbs":6,"title":2},"103":{"body":95,"breadcrumbs":6,"title":2},"104":{"body":231,"breadcrumbs":5,"title":1},"105":{"body":148,"breadcrumbs":5,"title":1},"106":{"body":6,"breadcrumbs":7,"title":3},"107":{"body":109,"breadcrumbs":6,"title":2},"108":{"body":123,"breadcrumbs":5,"title":1},"109":{"body":16,"breadcrumbs":2,"title":1},"11":{"body":44,"breadcrumbs":4,"title":1},"110":{"body":38,"breadcrumbs":2,"title":1},"111":{"body":188,"breadcrumbs":2,"title":1},"112":{"body":125,"breadcrumbs":3,"title":2},"113":{"body":25,"breadcrumbs":2,"title":1},"114":{"body":28,"breadcrumbs":3,"title":2},"115":{"body":46,"breadcrumbs":2,"title":1},"116":{"body":62,"breadcrumbs":3,"title":2},"117":{"body":34,"breadcrumbs":3,"title":2},"118":{"body":49,"breadcrumbs":3,"title":2},"119":{"body":105,"breadcrumbs":2,"title":1},"12":{"body":68,"breadcrumbs":5,"title":2},"120":{"body":59,"breadcrumbs":3,"title":2},"121":{"body":114,"breadcrumbs":3,"title":2},"122":{"body":65,"breadcrumbs":3,"title":2},"123":{"body":68,"breadcrumbs":3,"title":2},"124":{"body":29,"breadcrumbs":2,"title":1},"125":{"body":139,"breadcrumbs":2,"title":1},"126":{"body":43,"breadcrumbs":2,"title":1},"127":{"body":0,"breadcrumbs":3,"title":2},"128":{"body":118,"breadcrumbs":3,"title":2},"129":{"body":174,"breadcrumbs":6,"title":5},"13":{"body":31,"breadcrumbs":4,"title":1},"130":{"body":77,"breadcrumbs":4,"title":3},"131":{"body":89,"breadcrumbs":4,"title":3},"132":{"body":249,"breadcrumbs":4,"title":3},"133":{"body":100,"breadcrumbs":4,"title":3},"134":{"body":190,"breadcrumbs":2,"title":1},"135":{"body":18,"breadcrumbs":2,"title":1},"136":{"body":86,"breadcrumbs":2,"title":1},"137":{"body":118,"breadcrumbs":3,"title":2},"138":{"body":23,"breadcrumbs":2,"title":1},"139":{"body":87,"breadcrumbs":2,"title":1},"14":{"body":33,"breadcrumbs":4,"title":1},"140":{"body":46,"breadcrumbs":2,"title":1},"141":{"body":0,"breadcrumbs":3,"title":2},"142":{"body":127,"breadcrumbs":4,"title":3},"143":{"body":392,"breadcrumbs":6,"title":5},"144":{"body":35,"breadcrumbs":4,"title":3},"145":{"body":26,"breadcrumbs":2,"title":1},"146":{"body":26,"breadcrumbs":2,"title":1},"147":{"body":75,"breadcrumbs":2,"title":1},"148":{"body":16,"breadcrumbs":2,"title":1},"149":{"body":18,"breadcrumbs":3,"title":2},"15":{"body":69,"breadcrumbs":4,"title":1},"150":{"body":25,"breadcrumbs":2,"title":1},"151":{"body":122,"breadcrumbs":3,"title":2},"152":{"body":50,"breadcrumbs":2,"title":1},"153":{"body":12,"breadcrumbs":4,"title":3},"154":{"body":45,"breadcrumbs":3,"title":2},"155":{"body":31,"breadcrumbs":3,"title":2},"156":{"body":0,"breadcrumbs":3,"title":2},"157":{"body":26,"breadcrumbs":4,"title":3},"158":{"body":49,"breadcrumbs":4,"title":3},"159":{"body":33,"breadcrumbs":4,"title":3},"16":{"body":15,"breadcrumbs":4,"title":1},"160":{"body":105,"breadcrumbs":3,"title":2},"161":{"body":87,"breadcrumbs":2,"title":1},"162":{"body":116,"breadcrumbs":4,"title":3},"163":{"body":362,"breadcrumbs":4,"title":3},"164":{"body":49,"breadcrumbs":2,"title":1},"165":{"body":38,"breadcrumbs":3,"title":2},"166":{"body":97,"breadcrumbs":3,"title":2},"167":{"body":0,"breadcrumbs":3,"title":2},"168":{"body":53,"breadcrumbs":3,"title":2},"169":{"body":169,"breadcrumbs":6,"title":5},"17":{"body":8,"breadcrumbs":4,"title":1},"170":{"body":80,"breadcrumbs":3,"title":1},"171":{"body":61,"breadcrumbs":4,"title":2},"172":{"body":29,"breadcrumbs":3,"title":1},"173":{"body":52,"breadcrumbs":3,"title":1},"174":{"body":48,"breadcrumbs":3,"title":1},"175":{"body":42,"breadcrumbs":3,"title":1},"176":{"body":62,"breadcrumbs":4,"title":2},"177":{"body":209,"breadcrumbs":5,"title":3},"178":{"body":159,"breadcrumbs":6,"title":4},"179":{"body":67,"breadcrumbs":5,"title":3},"18":{"body":4,"breadcrumbs":4,"title":1},"180":{"body":91,"breadcrumbs":5,"title":3},"181":{"body":49,"breadcrumbs":5,"title":3},"182":{"body":50,"breadcrumbs":5,"title":3},"183":{"body":18,"breadcrumbs":4,"title":2},"184":{"body":143,"breadcrumbs":3,"title":1},"185":{"body":38,"breadcrumbs":4,"title":2},"186":{"body":38,"breadcrumbs":4,"title":2},"187":{"body":22,"breadcrumbs":6,"title":4},"188":{"body":34,"breadcrumbs":4,"title":2},"189":{"body":45,"breadcrumbs":4,"title":2},"19":{"body":0,"breadcrumbs":4,"title":1},"190":{"body":121,"breadcrumbs":4,"title":2},"191":{"body":40,"breadcrumbs":4,"title":2},"192":{"body":64,"breadcrumbs":3,"title":1},"193":{"body":98,"breadcrumbs":3,"title":1},"194":{"body":18,"breadcrumbs":5,"title":3},"195":{"body":79,"breadcrumbs":3,"title":1},"196":{"body":12,"breadcrumbs":3,"title":1},"197":{"body":73,"breadcrumbs":4,"title":2},"198":{"body":57,"breadcrumbs":5,"title":3},"199":{"body":332,"breadcrumbs":5,"title":3},"2":{"body":41,"breadcrumbs":2,"title":1},"20":{"body":34,"breadcrumbs":4,"title":1},"200":{"body":261,"breadcrumbs":6,"title":4},"201":{"body":75,"breadcrumbs":5,"title":3},"202":{"body":57,"breadcrumbs":3,"title":1},"203":{"body":173,"breadcrumbs":4,"title":2},"204":{"body":98,"breadcrumbs":3,"title":1},"205":{"body":50,"breadcrumbs":5,"title":2},"206":{"body":103,"breadcrumbs":5,"title":2},"207":{"body":85,"breadcrumbs":4,"title":1},"208":{"body":92,"breadcrumbs":8,"title":5},"209":{"body":87,"breadcrumbs":7,"title":4},"21":{"body":12,"breadcrumbs":5,"title":2},"210":{"body":179,"breadcrumbs":4,"title":1},"211":{"body":116,"breadcrumbs":5,"title":2},"212":{"body":191,"breadcrumbs":5,"title":2},"213":{"body":48,"breadcrumbs":2,"title":1},"214":{"body":157,"breadcrumbs":5,"title":4},"215":{"body":386,"breadcrumbs":2,"title":1},"216":{"body":42,"breadcrumbs":5,"title":4},"217":{"body":144,"breadcrumbs":4,"title":3},"218":{"body":188,"breadcrumbs":5,"title":4},"219":{"body":79,"breadcrumbs":4,"title":3},"22":{"body":15,"breadcrumbs":4,"title":1},"220":{"body":35,"breadcrumbs":3,"title":2},"221":{"body":54,"breadcrumbs":2,"title":1},"222":{"body":114,"breadcrumbs":2,"title":1},"223":{"body":73,"breadcrumbs":3,"title":2},"224":{"body":52,"breadcrumbs":3,"title":2},"225":{"body":56,"breadcrumbs":4,"title":3},"226":{"body":48,"breadcrumbs":4,"title":2},"227":{"body":128,"breadcrumbs":4,"title":2},"228":{"body":11,"breadcrumbs":4,"title":2},"229":{"body":70,"breadcrumbs":5,"title":3},"23":{"body":91,"breadcrumbs":4,"title":1},"230":{"body":62,"breadcrumbs":6,"title":4},"231":{"body":57,"breadcrumbs":6,"title":4},"232":{"body":118,"breadcrumbs":8,"title":6},"233":{"body":33,"breadcrumbs":4,"title":2},"234":{"body":78,"breadcrumbs":4,"title":2},"235":{"body":97,"breadcrumbs":5,"title":3},"236":{"body":90,"breadcrumbs":3,"title":1},"237":{"body":36,"breadcrumbs":4,"title":2},"238":{"body":231,"breadcrumbs":5,"title":3},"239":{"body":5,"breadcrumbs":2,"title":2},"24":{"body":82,"breadcrumbs":5,"title":2},"240":{"body":29,"breadcrumbs":3,"title":2},"241":{"body":102,"breadcrumbs":3,"title":2},"242":{"body":161,"breadcrumbs":4,"title":3},"25":{"body":71,"breadcrumbs":5,"title":2},"26":{"body":64,"breadcrumbs":4,"title":1},"27":{"body":27,"breadcrumbs":4,"title":1},"28":{"body":0,"breadcrumbs":4,"title":1},"29":{"body":70,"breadcrumbs":6,"title":3},"3":{"body":139,"breadcrumbs":2,"title":1},"30":{"body":145,"breadcrumbs":5,"title":2},"31":{"body":196,"breadcrumbs":4,"title":1},"32":{"body":27,"breadcrumbs":4,"title":1},"33":{"body":115,"breadcrumbs":6,"title":3},"34":{"body":13,"breadcrumbs":4,"title":1},"35":{"body":31,"breadcrumbs":4,"title":1},"36":{"body":151,"breadcrumbs":5,"title":2},"37":{"body":125,"breadcrumbs":7,"title":4},"38":{"body":87,"breadcrumbs":5,"title":2},"39":{"body":135,"breadcrumbs":4,"title":1},"4":{"body":34,"breadcrumbs":2,"title":1},"40":{"body":53,"breadcrumbs":4,"title":1},"41":{"body":108,"breadcrumbs":5,"title":2},"42":{"body":128,"breadcrumbs":6,"title":2},"43":{"body":68,"breadcrumbs":5,"title":1},"44":{"body":43,"breadcrumbs":5,"title":1},"45":{"body":5,"breadcrumbs":5,"title":1},"46":{"body":97,"breadcrumbs":5,"title":1},"47":{"body":75,"breadcrumbs":5,"title":1},"48":{"body":26,"breadcrumbs":5,"title":1},"49":{"body":25,"breadcrumbs":6,"title":3},"5":{"body":31,"breadcrumbs":4,"title":2},"50":{"body":0,"breadcrumbs":6,"title":3},"51":{"body":74,"breadcrumbs":4,"title":1},"52":{"body":39,"breadcrumbs":7,"title":4},"53":{"body":43,"breadcrumbs":6,"title":3},"54":{"body":92,"breadcrumbs":5,"title":2},"55":{"body":114,"breadcrumbs":5,"title":2},"56":{"body":77,"breadcrumbs":6,"title":3},"57":{"body":174,"breadcrumbs":6,"title":3},"58":{"body":146,"breadcrumbs":6,"title":3},"59":{"body":48,"breadcrumbs":5,"title":2},"6":{"body":71,"breadcrumbs":4,"title":1},"60":{"body":129,"breadcrumbs":5,"title":2},"61":{"body":0,"breadcrumbs":4,"title":1},"62":{"body":124,"breadcrumbs":4,"title":1},"63":{"body":79,"breadcrumbs":6,"title":3},"64":{"body":67,"breadcrumbs":4,"title":1},"65":{"body":182,"breadcrumbs":5,"title":2},"66":{"body":136,"breadcrumbs":4,"title":1},"67":{"body":110,"breadcrumbs":5,"title":2},"68":{"body":21,"breadcrumbs":4,"title":1},"69":{"body":116,"breadcrumbs":4,"title":1},"7":{"body":48,"breadcrumbs":4,"title":1},"70":{"body":5,"breadcrumbs":2,"title":1},"71":{"body":21,"breadcrumbs":2,"title":1},"72":{"body":79,"breadcrumbs":2,"title":1},"73":{"body":64,"breadcrumbs":3,"title":2},"74":{"body":41,"breadcrumbs":3,"title":2},"75":{"body":97,"breadcrumbs":2,"title":1},"76":{"body":82,"breadcrumbs":4,"title":3},"77":{"body":20,"breadcrumbs":4,"title":2},"78":{"body":137,"breadcrumbs":3,"title":1},"79":{"body":111,"breadcrumbs":3,"title":1},"8":{"body":97,"breadcrumbs":4,"title":1},"80":{"body":162,"breadcrumbs":6,"title":4},"81":{"body":44,"breadcrumbs":4,"title":2},"82":{"body":44,"breadcrumbs":4,"title":2},"83":{"body":137,"breadcrumbs":6,"title":2},"84":{"body":7,"breadcrumbs":6,"title":2},"85":{"body":34,"breadcrumbs":6,"title":3},"86":{"body":42,"breadcrumbs":4,"title":1},"87":{"body":67,"breadcrumbs":7,"title":4},"88":{"body":64,"breadcrumbs":7,"title":4},"89":{"body":65,"breadcrumbs":5,"title":2},"9":{"body":0,"breadcrumbs":4,"title":1},"90":{"body":59,"breadcrumbs":7,"title":4},"91":{"body":40,"breadcrumbs":8,"title":5},"92":{"body":98,"breadcrumbs":5,"title":2},"93":{"body":187,"breadcrumbs":8,"title":3},"94":{"body":84,"breadcrumbs":6,"title":2},"95":{"body":80,"breadcrumbs":6,"title":2},"96":{"body":229,"breadcrumbs":6,"title":2},"97":{"body":51,"breadcrumbs":6,"title":2},"98":{"body":77,"breadcrumbs":6,"title":2},"99":{"body":54,"breadcrumbs":6,"title":2}},"docs":{"0":{"body":"Welcome to Move, a next generation language for secure asset programming. Its primary use case is in blockchain environments, where Move programs are used to construct state changes. 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":"The Move Reference » The Move Reference","id":"0","title":"The Move Reference"},"1":{"body":"Modules are the core program unit that define types along with functions that operate on these types. Struct types define the schema of Move's storage , and module functions define the rules interacting with values of those types. While modules themselves are also stored in storage, they are not accessible from within a Move program. In a blockchain environment, the modules are stored on chain in a process typically referred to as \"publishing\". After being published, entry and public functions can be invoked according to the rules of that particular Move instance.","breadcrumbs":"Modules » Modules","id":"1","title":"Modules"},"10":{"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":"Primitive Types » Integers » Arithmetic","id":"10","title":"Arithmetic"},"100":{"body":"Patterns are not expressions, but they are nevertheless typed. This means that the type of a pattern must match the type of the value it matches. For example, the pattern 1 has an integer type, the pattern MyEnum::Variant(1, true) has type MyEnum, the pattern MyStruct { x, y } has type MyStruct, and OtherStruct { x: true, y: 1} has type OtherStruct. If you try to match on an expression that differs from the type of the pattern in the match, this will result in a type error. For example: match (1) { // The `true` literal pattern is of type `bool` so this is a type error. true => 1, // TYPE ERROR: expected type u64, found bool _ => 2,\n} Similarly, the following would also result in a type error because MyEnum and MyStruct are different types: match (MyStruct { x: 0, y: 0 }) { MyEnum::Variant(..) => 1, // TYPE ERROR: expected type MyEnum, found MyStruct\n}","breadcrumbs":"Control Flow » Patterm Matching » Pattern Typing","id":"100","title":"Pattern Typing"},"101":{"body":"Prior to delving into the specifics of pattern matching and what it means for a value to \"match\" a pattern, let's examine a few examples to provide an intuition for the concept. fun test_lit(x: u64): u8 { match (x) { 1 => 2, 2 => 3, _ => 4, }\n}\ntest_lit(1); // returns 2\ntest_lit(2); // returns 3\ntest_lit(3); // returns 4\ntest_lit(10); // returns 4 fun test_var(x: u64): u64 { match (x) { y => y, }\n}\ntest_var(1); // returns 1\ntest_var(2); // returns 2\ntest_var(3); // returns 3\n... const MyConstant: u64 = 10;\nfun test_constant(x: u64): u64 { match (x) { MyConstant => 1, _ => 2, }\n}\ntest_constant(MyConstant); // returns 1\ntest_constant(10); // returns 1\ntest_constant(20); // returns 2 fun test_or_pattern(x: u64): u64 { match (x) { 1 | 2 | 3 => 1, 4 | 5 | 6 => 2, _ => 3, }\n}\ntest_or_pattern(3); // returns 1\ntest_or_pattern(5); // returns 2\ntest_or_pattern(70); // returns 3 fun test_or_at_pattern(x: u64): u64 { match (x) { x @ (1 | 2 | 3) => x + 1, y @ (4 | 5 | 6) => y + 2, z => z + 3, }\n}\ntest_or_pattern(2); // returns 3\ntest_or_pattern(5); // returns 7\ntest_or_pattern(70); // returns 73 The most important thing to note from these examples is that a pattern matches a value if the value is equal to the pattern, and wildcard/variable patterns match anything. This is true for literals, variables, and constants. For example, in the test_lit function, the value 1 matches the pattern 1, the value 2 matches the pattern 2, and the value 3 matches the wildcard _. Similarly, in the test_var function, both the value 1 and the value 2 matches the pattern y. A variable x matches (or \"equals\") any value, and a wildcard _ matches any value (but only one value). Or-patterns are like a logical OR, where a value matches the pattern if it matches any of patterns in the or-pattern so p1 | p2 | p3 should be read \"matches p1, or p2, or p3\".","breadcrumbs":"Control Flow » Patterm Matching » Matching","id":"101","title":"Matching"},"102":{"body":"Pattern matching includes the concept of constructor patterns. These patterns allow you to inspect and access deep within both structs and enums, and are one of the most powerful parts of pattern matching. Constructor patterns, coupled with variable bindings, allow you to match on values by their structure, and pull out the parts of the value you care about for usage on the right-hand side of the match arm. Take the following: fun f(x: MyEnum) { match (x) { MyEnum::Variant(1, true) => 1, MyEnum::OtherVariant(_, 3) => 2, MyEnum::Variant(..) => 3, MyEnum::OtherVariant(..) => 4,\n}\nf(MyEnum::Variant(1, true)); // returns 1\nf(MyEnum::Variant(2, true)); // returns 3\nf(MyEnum::OtherVariant(false, 3)); // returns 2\nf(MyEnum::OtherVariant(true, 3)); // returns 2\nf(MyEnum::OtherVariant(true, 2)); // returns 4 This is saying that \"if x is MyEnum::Variant with the fields 1 and true, then return 1. If it is MyEnum::OtherVariant with any value for the first field, and 3 for the second, then return 2. If it is MyEnum::Variant with any fields, then return 3. Finally, if it is MyEnum::OtherVariant with any fields, then return 4\". You can also nest patterns. So, if you wanted to match either 1, 2, or 10, instead of just matching 1 in the previous MyEnum::Variant, you could do so with an or-pattern: fun f(x: MyEnum) { match (x) { MyEnum::Variant(1 | 2 | 10, true) => 1, MyEnum::OtherVariant(_, 3) => 2, MyEnum::Variant(..) => 3, MyEnum::OtherVariant(..) => 4,\n}\nf(MyEnum::Variant(1, true)); // returns 1\nf(MyEnum::Variant(2, true)); // returns 1\nf(MyEnum::Variant(10, true)); // returns 1\nf(MyEnum::Variant(10, false)); // returns 3","breadcrumbs":"Control Flow » Patterm Matching » Matching Constructors","id":"102","title":"Matching Constructors"},"103":{"body":"Additionally, match bindings are subject to the same ability restrictions as other aspects of Move. In particular, the compiler will signal an error if you try to match a value (not-reference) without drop using a wildcard, as the wildcard expects to drop the value. Similarly, if you bind a non-drop value using a binder, it must be used in the right-hand side of the match arm. In addition, if you fully destruct that value, you have unpacked it, matching the semantics of non-drop struct unpacking . See the abilities section on drop for more details about the drop capability. public struct NonDrop(u64) fun drop_nondrop(x: NonDrop) { match (x) { NonDrop(1) => 1, _ => 2 // ERROR: cannot wildcard match on a non-droppable value }\n} fun destructure_nondrop(x: NonDrop) { match (x) { NonDrop(1) => 1, NonDrop(_) => 2 // OK! }\n} fun use_nondrop(x: NonDrop): NonDrop { match (x) { NonDrop(1) => NonDrop(8), x => x }\n}","breadcrumbs":"Control Flow » Patterm Matching » Ability Constraints","id":"103","title":"Ability Constraints"},"104":{"body":"The match expression in Move must be exhaustive : every possible value of the type being matched must be covered by one of the patterns in one of the match's arms. If the series of match arms is not exhaustive, the compiler will raise an error. Note that any arm with a guard expression does not contribute to match exhaustion, as it might fail to match at runtime. As an example, a match on a u8 is exhaustive only if it matches on every number from 0 to 255 inclusive, unless there is a wildcard or variable pattern present. Similarly, a match on a bool would need to match on both true and false, unless there is a wildcard or variable pattern present. For structs, because there is only one type of constructor for the type, only one constructor needs to be matched, but the fields within the struct need to be matched exhaustively as well. Conversely, enums may define multiple variants, and each variant must be matched (including any sub-fields) for the match to be considered exhaustive. Because underscores and variables are wildcards that match anything, they count as matching all values of the type they are matching on in that position. Additionally, the multi-arity wildcard pattern .. can be used to match on multiple values within a struct or enum variant. To see some examples of non-exhaustive matches, consider the following: public enum MyEnum { Variant(u64, bool), OtherVariant(bool, u64),\n} public struct Pair(T, T) fun f(x: MyEnum): u8 { match (x) { MyEnum::Variant(1, true) => 1, MyEnum::Variant(_, _) => 1, MyEnum::OtherVariant(_, 3) => 2, // ERROR: not exhaustive as the value `MyEnum::OtherVariant(_, 4)` is not matched. }\n} fun match_pair_bool(x: Pair): u8 { match (x) { Pair(true, true) => 1, Pair(true, false) => 1, Pair(false, false) => 1, // ERROR: not exhaustive as the value `Pair(false, true)` is not matched. }\n} These examples can then be made exhaustive by adding a wildcard pattern to the end of the match arm, or by fully matching on the remaining values: fun f(x: MyEnum): u8 { match (x) { MyEnum::Variant(1, true) => 1, MyEnum::Variant(_, _) => 1, MyEnum::OtherVariant(_, 3) => 2, // Now exhaustive since this will match all values of MyEnum::OtherVariant MyEnum::OtherVariant(..) => 2, }\n} fun match_pair_bool(x: Pair): u8 { match (x) { Pair(true, true) => 1, Pair(true, false) => 1, Pair(false, false) => 1, // Now exhaustive since this will match all values of Pair Pair(false, true) => 1, }\n}","breadcrumbs":"Control Flow » Patterm Matching » Exhaustiveness","id":"104","title":"Exhaustiveness"},"105":{"body":"As previously mentioned, you can add a guard to a match arm by adding an if clause after the pattern. This guard will run after the pattern has been matched but before the expression on the right hand side of the arrow is evaluated. If the guard expression evaluates to true then the expression on the right hand side of the arrow will be evaluated, if it evaluates to false then it will be considered a failed match and the next match arm in the match expression will be checked. fun match_with_guard(x: u64): u64 { match (x) { 1 if (false) => 1, 1 => 2, _ => 3, }\n} match_with_guard(1); // returns 2\nmatch_with_guard(0); // returns 3 Guard expressions can reference variables bound in the pattern during evaluation. However, note that variables are only available as immutable reference in guards regardless of the pattern being matched -- even if there are mutability specifiers on the variable or if the pattern is being matched by value. fun incr(x: &mut u64) { *x = *x + 1;\n} fun match_with_guard_incr(x: u64): u64 { match (x) { x if ({ incr(&mut x); x == 1 }) => 1, // ERROR: ^^^ invalid borrow of immutable value _ => 2, }\n} fun match_with_guard_incr2(x: &mut u64): u64 { match (x) { x if ({ incr(&mut x); x == 1 }) => 1, // ERROR: ^^^ invalid borrow of immutable value _ => 2, }\n} Additionally, it is important to note any match arms that have guard expressions will not be considered either for exhaustivity purposes because the compiler has no way of evaluating the guard expression statically.","breadcrumbs":"Control Flow » Patterm Matching » Guards","id":"105","title":"Guards"},"106":{"body":"There are some restrictions on when the .. and mut pattern modifiers can be used in a pattern.","breadcrumbs":"Control Flow » Patterm Matching » Limitations on Specific Patterns","id":"106","title":"Limitations on Specific Patterns"},"107":{"body":"A mut modifier can be placed on a variable pattern to specify that the variable is to be mutated in the right-hand expression of the match arm. Note that since the mut modifier only signifies that the variable is to be mutated, not the underlying data, this can be used on all types of match (by value, immutable reference, and mutable reference). Note that the mut modifier can only be applied to variables, and not other types of patterns. public struct MyStruct(u64) fun top_level_mut(x: MyStruct) { match (x) { mut MyStruct(y) => 1, // ERROR: cannot use mut on a non-variable pattern }\n} fun mut_on_immut(x: &MyStruct): u64 { match (x) { MyStruct(mut y) => { y = &(*y + 1); *y } }\n} fun mut_on_value(x: MyStruct): u64 { match (x) { MyStruct(mut y) => { *y = *y + 1; *y }, }\n} fun mut_on_mut(x: &mut MyStruct): u64 { match (x) { MyStruct(mut y) => { *y = *y + 1; *y }, }\n} let mut x = MyStruct(1); mut_on_mut(&mut x); // returns 2\nx.0; // returns 2 mut_on_immut(&x); // returns 3\nx.0; // returns 2 mut_on_value(x); // returns 3","breadcrumbs":"Control Flow » Patterm Matching » Mutability Usage","id":"107","title":"Mutability Usage"},"108":{"body":"The .. pattern can only be used within a constructor pattern as a wildcard that matches any number of fields -- the the compiler expands the .. to inserting _ in any missing fields in the constructor pattern (if any). So MyStruct(_, _, _) is the same as MyStruct(..), MyStruct(1, _, _) is the same as MyStruct(1, ..). Because of this, there are some restrictions on how, and where the .. pattern can be used: It can only be used once within the constructor pattern; In positional arguments it can be used at the beginning, middle, or end of the patterns within the constructor; In named arguments it can only be used at the end of the patterns within the constructor; public struct MyStruct(u64, u64, u64, u64) has drop; public struct MyStruct2 { x: u64, y: u64, z: u64, w: u64,\n} fun wild_match(x: MyStruct) { match (x) { MyStruct(.., 1) => 1, // OK! The `..` pattern can be used at the begining of the constructor pattern MyStruct(1, ..) => 2, // OK! The `..` pattern can be used at the end of the constructor pattern MyStruct(1, .., 1) => 3, // OK! The `..` pattern can be used at the middle of the constructor pattern MyStruct(1, .., 1, 1) => 4, MyStruct(..) => 5, }\n} fun wild_match2(x: MyStruct2) { match (x) { MyStruct2 { x: 1, .. } => 1, MyStruct2 { x: 1, w: 2 .. } => 2, MyStruct2 { .. } => 3, }\n}","breadcrumbs":"Control Flow » Patterm Matching » .. Usage","id":"108","title":".. Usage"},"109":{"body":"Functions are declared inside of modules and define the logic and behavior of the module. Functions can be reused, either being called from other functions or as entry points for execution.","breadcrumbs":"Functions » Functions","id":"109","title":"Functions"},"11":{"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":"Primitive Types » Integers » Bitwise","id":"11","title":"Bitwise"},"110":{"body":"Functions are declared with the fun keyword followed by the function name, type parameters, parameters, a return type, 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":"110","title":"Declaration"},"111":{"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 as entry points. module a::m { fun foo(): u64 { 0 } fun calls_foo(): u64 { foo() } // valid\n} module b::other { fun calls_m_foo(): u64 { a::m::foo() // ERROR!\n// ^^^^^^^^^^^ 'foo' is internal to 'a::m' }\n} To allow access from other modules, the function must be declared public or public(package). Tangential to visibility, an entry function can be called as an entry point for execution. public visibility A public function can be called by any function defined in any module. 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 as an entry point for execution. module a::m { public fun foo(): u64 { 0 } fun calls_foo(): u64 { foo() } // valid\n} module b::other { fun calls_m_foo(): u64 { a::m::foo() // valid }\n} Fore more details on the entry point to execution see the section below . public(package) visibility The public(package) visibility modifier is a more restricted form of the public modifier to give more control about where a function can be used. A public(package) function can be called by: other functions defined in the same module, or other functions defined in the same package (the same address) module a::m { public(package) fun foo(): u64 { 0 } fun calls_foo(): u64 { foo() } // valid\n} module a::n { fun calls_m_foo(): u64 { a::m::foo() // valid, also in `a` }\n} module b::other { fun calls_m_foo(): u64 { b::m::foo() // ERROR!\n// ^^^^^^^^^^^ 'foo' can only be called from a module in `a` }\n} DEPRECATED public(friend) visibility Before the addition of public(package), public(friend) was used to allow limited public access to functions in the same package, but where the list of allowed modules had to be explicitly enumerated by the callee's module. see Friends for more details.","breadcrumbs":"Functions » Visibility","id":"111","title":"Visibility"},"112":{"body":"In addition to public functions, you might have some functions in your modules that you want to use as the entry point to execution. The entry modifier is designed to allow module functions to initiate execution, without having to expose the functionality to other modules. Essentially, the combination of pbulic and entry functions define the \"main\" functions of a module, and they specify where Move programs can start executing. Keep in mind 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: module a::m { entry fun foo(): u64 { 0 } fun calls_foo(): u64 { foo() } // valid!\n} module a::n { fun calls_m_foo(): u64 { a::m::foo() // ERROR!\n// ^^^^^^^^^^^ 'foo' is internal to 'a::m' }\n} entry functions may have restrictions on their parameters and return types. Although, these restrictions are specific to each individual deployment of Move. The documentation for entry functions on Sui can be found here. . To enable easier testing, entry functions can be called from #[test] and #[test_only] contexts. module a::m { entry fun foo(): u64 { 0 }\n}\nmodule a::m_test { #[test] fun my_test(): u64 { a::m::foo() } // valid! #[test_only] fun my_test_helper(): u64 { a::m::foo() } // valid!\n}","breadcrumbs":"Functions » entry modifier","id":"112","title":"entry modifier"},"113":{"body":"Function names can start with 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 bAZ_19() {}","breadcrumbs":"Functions » Name","id":"113","title":"Name"},"114":{"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":"114","title":"Type Parameters"},"115":{"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 module a::example { public struct Counter { count: u64 } fun new_counter(): Counter { Counter { count: 0 } }\n}","breadcrumbs":"Functions » Parameters","id":"115","title":"Parameters"},"116":{"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() { } As mentioned in the tuples section , these tuple \"values\" do not exist as runtime values. This means that a function that returns unit () does not return any value during execution.","breadcrumbs":"Functions » Return type","id":"116","title":"Return type"},"117":{"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":"117","title":"Function body"},"118":{"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 length(v: &vector): u64; ...\n}","breadcrumbs":"Functions » Native Functions","id":"118","title":"Native Functions"},"119":{"body":"When calling a function, the name can be specified either through an alias or fully qualified module a::example { public fun zero(): u64 { 0 }\n} module b::other { use a::example::{Self, zero}; fun call_zero() { // With the `use` above all of these calls are equivalent a::example::zero(); example::zero(); zero(); }\n} When calling a function, an argument must be given for every parameter. module a::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} module b::other { fun call_all() { a::example::takes_none(); a::example::takes_one(0); a::example::takes_two(0, 1); a::example::takes_three(0, 1, 2); }\n} Type arguments can be either specified or inferred. Both calls are equivalent. module aexample { public fun id(x: T): T { x }\n} module b::other { fun call_all() { a::example::id(0); a::example::id(0); }\n} For more details, see Move generics .","breadcrumbs":"Functions » Calling","id":"119","title":"Calling"},"12":{"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":"Primitive Types » Integers » Bit Shifts","id":"12","title":"Bit Shifts"},"120":{"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} The return value here is the result of x + y. 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 the result of double_x + double_y","breadcrumbs":"Functions » Returning values","id":"120","title":"Returning values"},"121":{"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":"121","title":"return expression"},"122":{"body":"A struct is a user-defined data structure containing typed fields. Structs can store any non-reference, non-tuple type, including other structs. Structs can be used to define all \"asset\" values or unrestricted values, where the operations performed on those values can be controlled by the struct's abilities . By default, structs are linear and ephemeral. By this we mean that they: cannot be copied, cannot be dropped, and cannot be stored in 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 storage or to define storage schemas.","breadcrumbs":"Structs » Structs and Resources","id":"122","title":"Structs and Resources"},"123":{"body":"Structs must be defined inside a module, and the struct's fields can either be named or positional: module a::m { public struct Foo { x: u64, y: bool } public struct Bar {} public struct Baz { foo: Foo, } // ^ note: it is fine to have a trailing comma public struct PosFoo(u64, bool) public struct PosBar() public struct PosBaz(Foo)\n} Structs cannot be recursive, so the following definitions are invalid: public struct Foo { x: Foo }\n// ^ ERROR! recursive definition public struct A { b: B }\npublic struct B { a: A }\n// ^ ERROR! recursive definition public struct D(D)\n// ^ ERROR! recursive definition","breadcrumbs":"Structs » Defining Structs","id":"123","title":"Defining Structs"},"124":{"body":"As you may have noticed, all structs are declared as public. This means that the type of the struct can be referred to from any other module. However, the fields of the struct, and the ability to create or destroy the struct, are still internal to the module that defines the struct. In the future, we plan on adding to declare structs as public(package) or as internal, much like functions .","breadcrumbs":"Structs » Visibility","id":"124","title":"Visibility"},"125":{"body":"As mentioned above: by default, a struct declaration is linear and ephemeral. So to allow the value to be used in these ways (e.g., copied, dropped, stored in an object , or used to define a storable object ), structs can be granted abilities by annotating them with has : module a::m { public struct Foo has copy, drop { x: u64, y: bool }\n} The ability declaration can occur either before or after the struct's fields. However, only one or the other can be used, and not both. If declared after the struct's fields, the ability declaration must be terminated with a semicolon: module a::m { public struct PreNamedAbilities has copy, drop { x: u64, y: bool } public struct PostNamedAbilities { x: u64, y: bool } has copy, drop; public struct PostNamedAbilitiesInvalid { x: u64, y: bool } has copy, drop // ^ ERROR! missing semicolon public struct NamedInvalidAbilities has copy { x: u64, y: bool } has drop; // ^ ERROR! duplicate ability declaration public struct PrePositionalAbilities has copy, drop (u64, bool) public struct PostPositionalAbilities (u64, bool) has copy, drop; public struct PostPositionalAbilitiesInvalid (u64, bool) has copy, drop // ^ ERROR! missing semicolon public struct InvalidAbilities has copy (u64, bool) has drop; // ^ ERROR! duplicate ability declaration\n} For more details, see the section on annotating a struct's abilities .","breadcrumbs":"Structs » Abilities","id":"125","title":"Abilities"},"126":{"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. public struct Foo {}\npublic struct BAR {}\npublic struct B_a_z_4_2 {}\npublic struct P_o_s_Foo() 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 » Naming","id":"126","title":"Naming"},"127":{"body":"","breadcrumbs":"Structs » Using Structs","id":"127","title":"Using Structs"},"128":{"body":"Values of a struct type can be created (or \"packed\") by indicating the struct name, followed by value for each field. For a struct with named fields, the order of the fields does not matter, but the field name needs to be provided. For a struct with positional fields, the order of the fields must match the order of the fields in the struct definition, and it must be created using () instead of {} to enclose the parameters. module a::m { public struct Foo has drop { x: u64, y: bool } public struct Baz has drop { foo: Foo } public struct Positional(u64, bool) has drop; fun example() { let foo = Foo { x: 0, y: false }; let baz = Baz { foo: foo }; // Note: positional struct values are created using parentheses and // based on position instead of name. let pos = Positional(0, false); let pos_invalid = Positional(false, 0); // ^ ERROR! Fields are out of order and the types don't match. }\n} For structs with named fields, you can use the following shorthand if you have a local variable with the same name as the field: let baz = Baz { foo: foo };\n// is equivalent to\nlet baz = Baz { foo }; This is sometimes called \"field name punning\".","breadcrumbs":"Structs » Creating Structs","id":"128","title":"Creating Structs"},"129":{"body":"Struct values can be destroyed by binding or assigning them in patterns using similar syntax to constructing them. module a::m { public struct Foo { x: u64, y: bool } public struct Bar(Foo) public struct Baz {} public struct Qux() 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 and 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 { x: 3, y: false }); let Bar(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; } fun example_destroy_qux() { let qux = Qux(); let Qux() = qux; }\n}","breadcrumbs":"Structs » Destroying Structs via Pattern Matching","id":"129","title":"Destroying Structs via Pattern Matching"},"13":{"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 must 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":"Primitive Types » Integers » Comparisons","id":"13","title":"Comparisons"},"130":{"body":"Fields of a struct can be accessed using the dot operator .. For structs with named fields, the fields can be accessed by their name: public struct Foo { x: u64, y: bool }\nlet foo = Foo { x: 3, y: true };\nlet x = foo.x; // x == 3\nlet y = foo.y; // y == true For positional structs, fields can be accessed by their position in the struct definition: public struct PosFoo(u64, bool)\nlet pos_foo = PosFoo(3, true);\nlet x = pos_foo.0; // x == 3\nlet y = pos_foo.1; // y == true Accessing struct fields without borrowing or copying them is subject to the field's ability constraints. For more details see the sections on borrowing structs and fields and reading and writing fields for more information.","breadcrumbs":"Structs » Accessing Struct Fields","id":"130","title":"Accessing Struct Fields"},"131":{"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; // borrowing a field by extending a reference to the struct 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.0.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 » Borrowing Structs and Fields","id":"131","title":"Borrowing Structs and Fields"},"132":{"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(copy foo);\nlet x: u64 = *&foo.x;\nlet y: bool = *&foo.y;\nlet foo2: Foo = *&bar.0; More canonically, the dot operator can be used to read fields of a struct without any borrowing. As is true with dereferencing , the field type must have the copy ability . 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 bar = Bar(Foo { x: 3, y: true });\nlet x = baz.0.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.0;\nlet foo3: Foo = bar.0; // error! must add an explicit copy with *& We can mutably borrow a field to a struct to assign it a new value: let mut foo = Foo { x: 3, y: true };\n*&mut foo.x = 42; // foo = Foo { x: 42, y: true }\n*&mut foo.y = !foo.y; // foo = Foo { x: 42, y: false }\nlet mut bar = Bar(foo); // bar = Bar(Foo { x: 42, y: false })\n*&mut bar.0.x = 52; // bar = Bar(Foo { x: 52, y: false })\n*&mut bar.0 = Foo { x: 62, y: true }; // bar = Bar(Foo { x: 62, y: true }) Similar to dereferencing, we can instead directly use the dot operator to modify a field. And in both cases, the field type must have the drop ability . let mut 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 mut bar = Bar(foo); // bar = Bar(Foo { x: 42, y: false })\nbar.0.x = 52; // bar = Bar(Foo { x: 52, y: false })\nbar.0 = Foo { x: 62, y: true }; // bar = Bar(Foo { x: 62, y: true }) The dot syntax for assignment 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 » Reading and Writing Fields","id":"132","title":"Reading and Writing Fields"},"133":{"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 as stated in the visibility section above , struct types are always visible to another module module a::m { public struct Foo has drop { x: u64 } public fun new_foo(): Foo { Foo { x: 42 } }\n} module a::n { use a::m::Foo; public struct Wrapper has drop { foo: Foo // ^ valid the type is public } fun f1(foo: Foo) { let x = foo.x; // ^ ERROR! cannot access fields of `Foo` outside of `a::m` } fun f2() { let foo_wrapper = Wrapper { foo: m::new_foo() }; // ^ valid the function is public }\n}","breadcrumbs":"Structs » Privileged Struct Operations","id":"133","title":"Privileged Struct Operations"},"134":{"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 assets like money, as you do not want money to be duplicated or get lost in circulation. module a::m { public struct Foo { x: u64 } public fun copying() { 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_1() { let foo = Foo { x: 100 }; // error! when the function returns, foo still contains a value. // This destruction requires the 'drop' ability } public fun destroying_2(f: &mut Foo) { *f = Foo { x: 100 } // error! // destroying the old value via a write requires the 'drop' ability }\n} To fix the example fun destroying_1, you would need to manually \"unpack\" the value: module a::m { public struct Foo { x: u64 } public fun destroying_1_fixed() { let foo = Foo { x: 100 }; let Foo { x: _ } = foo; }\n} Recall that you are only able to deconstruct a struct 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: module a::m { public struct Foo has copy, drop { x: u64 } public fun run() { let foo = Foo { x: 100 }; let foo_copy = foo; // ^ this code copies foo, // whereas `let x = move foo` would 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}","breadcrumbs":"Structs » Ownership","id":"134","title":"Ownership"},"135":{"body":"Structs can be used to define storage schemas, but the details are different per deployment of Move. See the documentation for the key ability and Sui objects for more details.","breadcrumbs":"Structs » Storage","id":"135","title":"Storage"},"136":{"body":"An enum is a user-defined data structure containing one or more variants . Each variant can optionally contain typed fields. The number, and types of these fields can differ for each variant in the enumeration. Fields in enums can store any non-reference, non-tuple type, including other structs or enums. As a simple example, consider the following enum definition in Move: public enum Action { Stop, Pause { duration: u32 }, MoveTo { x: u64, y: u64 }, Jump(u64),\n} This declares an enum Action that represents different actions that can be taken by a game -- you can Stop, Pause for a given duration, MoveTo a specific location, or Jump to a specific height. Similar to structs, enums can have abilities that control what operations can be performed on them. It is important to note however that enums cannot have the key ability since they cannot be top-level objects.","breadcrumbs":"Enums » Enumerations","id":"136","title":"Enumerations"},"137":{"body":"Enums must be defined in a module, an enum must contain at least one variant, and each variant of an enum can either have no fields, positional fields, or named fields. Here are some examples of each: module a::m { public enum Foo has drop { VariantWithNoFields, // ^ note: it is fine to have a trailing comma after variant declarations } public enum Bar has copy, drop { VariantWithPositionalFields(u64, bool), } public enum Baz has drop { VariantWithNamedFields { x: u64, y: bool, z: Bar }, }\n} Enums cannot be recursive in any of their variants, so the following definitions of an enum are not allowed because they would be recursive in at least one variant. Incorrect: module a::m { public enum Foo { Recursive(Foo), // ^ error: recursive enum variant } public enum List { Nil, Cons { head: u64, tail: List }, // ^ error: recursive enum variant } public enum BTree { Leaf(T), Node { left: BTree, right: BTree }, // ^ error: recursive enum variant } // Mutually recursive enums are also not allowed public enum MutuallyRecursiveA { Base, Other(MutuallyRecursiveB), // ^^^^^^^^^^^^^^^^^^ error: recursive enum variant } public enum MutuallyRecursiveB { Base, Other(MutuallyRecursiveA), // ^^^^^^^^^^^^^^^^^^ error: recursive enum variant }\n}","breadcrumbs":"Enums » Defining Enums","id":"137","title":"Defining Enums"},"138":{"body":"All enums are declared as public. This means that the type of the enum can be referred to from any other module. However, the variants of the enum, the fields within each variant, and the ability to create or destroy variants of the enum are internal to the module that defines the enum.","breadcrumbs":"Enums » Visibility","id":"138","title":"Visibility"},"139":{"body":"Just like with structs, by default an enum declaration is linear and ephemeral. To use an enum value in a non-linear or non-ephemeral way -- i.e., copied, dropped, or stored in an object -- you need to grant it additional abilities by annotating them with has : module a::m { public enum Foo has copy, drop { VariantWithNoFields, }\n} The ability declaration can occur either before or after the enum's variants, however only one or the other can be used, and not both. If declared after the variants, the ability declaration must be terminated with a semicolon: module a::m { public enum PreNamedAbilities has copy, drop { Variant } public enum PostNamedAbilities { Variant } has copy, drop; public enum PostNamedAbilitiesInvalid { Variant } has copy, drop // ^ ERROR! missing semicolon public enum NamedInvalidAbilities has copy { Variant } has drop; // ^ ERROR! duplicate ability declaration\n} For more details, see the section on annotating abilities .","breadcrumbs":"Enums » Abilities","id":"139","title":"Abilities"},"14":{"body":"Like all types with drop , all integer types support the \"equal\" and \"not equal\" operations. Both arguments need to be of the same type. If you need to compare integers of different types, you must cast one of them first. Equality operations do not abort. Syntax Operation == equal != not equal For more details see the section on equality","breadcrumbs":"Primitive Types » Integers » Equality","id":"14","title":"Equality"},"140":{"body":"Enums and variants within enums must start with a capital letter A to Z. After the first letter, enum names can contain underscores _, lowercase letters a to z, uppercase letters A to Z, or digits 0 to 9. public enum Foo { Variant }\npublic enum BAR { Variant }\npublic enum B_a_z_4_2 { V_a_riant_0 } This naming restriction of starting with A to Z is in place to give room for future language features.","breadcrumbs":"Enums » Naming","id":"140","title":"Naming"},"141":{"body":"","breadcrumbs":"Enums » Using Enums","id":"141","title":"Using Enums"},"142":{"body":"Values of an enum type can be created (or \"packed\") by indicating a variant of the enum, followed by a value for each field in the variant. The variant name must always be qualified by the enum's name. Similarly to structs, for a variant with named fields, the order of the fields does not matter but the field names need to be provided. For a variant with positional fields, the order of the fields matters and the order of the fields must match the order in the variant declaration. It must also be created using () instead of {}. If the variant has no fields, the variant name is sufficient and no () or {} needs to be used. module a::m { public enum Action has drop { Stop, Pause { duration: u32 }, MoveTo { x: u64, y: u64 }, Jump(u64), } public enum Other has drop { Stop(u64), } fun example() { // Note: The `Stop` variant of `Action` doesn't have fields so no parentheses or curlies are needed. let stop = Action::Stop; let pause = Action::Pause { duration: 10 }; let move_to = Action::MoveTo { x: 10, y: 20 }; let jump = Action::Jump(10); // Note: The `Stop` variant of `Other` does have positional fields so we need to supply them. let other_stop = Other::Stop(10); }\n} For variants with named fields you can also use the shorthand syntax that you might be familiar with from structs to create the variant: let duration = 10; let pause = Action::Pause { duration: duration };\n// is equivalent to\nlet pause = Action::Pause { duration };","breadcrumbs":"Enums » Creating Enum Variants","id":"142","title":"Creating Enum Variants"},"143":{"body":"Since enum values can take on different shapes, dot access to fields of variants is not allowed like it is for struct fields. Instead, to access fields within a variant -- either by value, or immutable or mutable reference -- you must use pattern matching. You can pattern match on Move values by value, immutable reference, and mutable reference. When pattern matching by value, the value is moved into the match arm. When pattern matching by reference, the value is borrowed into the match arm (either immutably or mutably). We'll go through a brief description of pattern matching using match here, but for more information on pattern matching using match in Move see the Pattern Matching section. A match statement is used to pattern match on a Move value and consists of a number of match arms . Each match arm consists of a pattern, an arrow =>, and an expression, followed by a comma ,. The pattern can be a struct, enum variant, binding (x, y), wildcard (_ or ..), constant (ConstValue), or literal value (true, 42, and so on). The value is matched against each pattern from the top-down, and will match the first pattern that structurally matches the value. Once the value is matched, the expression on the right hand side of the => is executed. Additionally, match arms can have optional guards that are checked after the pattern matches but before the expression is executed. Guards are specified by the if keyword followed by an expression that must evaluate to a boolean value before the =>. module a::m { public enum Action has drop { Stop, Pause { duration: u32 }, MoveTo { x: u64, y: u64 }, Jump(u64), } public struct GameState { // Fields containing a game state character_x: u64, character_y: u64, character_height: u64, // ... } fun perform_action(stat: &mut GameState, action: Action) { match (action) { // Handle the `Stop` variant Action::Stop => state.stop(), // Handle the `Pause` variant // If the duration is 0, do nothing Action::Pause { duration: 0 } => (), Action::Pause { duration } => state.pause(duration), // Handle the `MoveTo` variant Action::MoveTo { x, y } => state.move_to(x, y), // Handle the `Jump` variant // if the game disallows jumps then do nothing Action::Jump(_) if (state.jumps_not_allowed()) => (), // otherwise, jump to the specified height Action::Jump(height) => state.jump(height), } }\n} To see how to pattern match on an enum to update values within it mutably, let's take the following example of a simple enum that has two variants, each with a single field. We can then write two functions, one that only increments the value of the first variant, and another that only increments the value of the second variant: module a::m { public enum SimpleEnum { Variant1(u64), Variant2(u64), } public fun incr_enum_variant1(simple_enum: &mut SimpleEnum) { match simple_enum { SimpleEnum::Variant1(mut value) => *value += 1, _ => (), } } public fun incr_enum_variant2(simple_enum: &mut SimpleEnum) { match simple_enum { SimpleEnum::Variant2(mut value) => *value += 1, _ => (), } }\n} Now, if we have a value of SimpleEnum we can use the functions to increment the value of this variant: let mut x = SimpleEnum::Variant1(10);\nincr_enum_variant1(&mut x);\nassert!(x == SimpleEnum::Variant1(11));\n// Doesn't increment since it increments a different variant\nincr_enum_variant2(&mut x);\nassert!(x == SimpleEnum::Variant1(11)); When pattern matching on a Move value that does not have the drop ability, the value must be consumed or destructured in each match arm. If the value is not consumed or destructured in a match arm, the compiler will raise an error. This is to ensure that all possible values are handled in the match statement. As an example, consider the following code: module a::m { public enum X { Variant { x: u64 } } public fun bad(x: X) { match x { _ => () // ^ ERROR! value of type `X` is not consumed or destructured in this match arm } }\n} To properly handle this, you will need to destructure X and all its variants in the match's arm(s): module a::m { public enum X { Variant { x: u64 } } public fun good(x: X) { match x { // OK! Compiles since the value is destructured X::Variant { x: _ } => () } }\n}","breadcrumbs":"Enums » Pattern Matching Enum Variants and Destructuring","id":"143","title":"Pattern Matching Enum Variants and Destructuring"},"144":{"body":"As long as the enum has the drop ability, you can overwrite the value of an enum with a new value of the same type just as you might with other values in Move. module a::m { public enum X has drop { A(u64), B(u64), } public fun overwrite_enum(x: &mut X) { *x = X::A(10); }\n} let mut x = X::B(20);\noverwrite_enum(&mut x);\nassert!(x == X::A(10));","breadcrumbs":"Enums » Overwriting to Enum Values","id":"144","title":"Overwriting to Enum Values"},"145":{"body":"Constants are a way of giving a name to shared, static values inside of a module. The constant's value must be known at compilation. The constant's value is stored in the compiled module. And each time the constant is used, a new copy of that value is made.","breadcrumbs":"Constants » Constants","id":"145","title":"Constants"},"146":{"body":"Constant declarations begin with the const keyword, followed by a name, a type, and a value. const : = ; For example module a::example { const MY_ADDRESS: address = @a; public fun permissioned(addr: address) { assert!(addr == MY_ADDRESS, 0); }\n}","breadcrumbs":"Constants » Declaration","id":"146","title":"Declaration"},"147":{"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 EMyErrorCode: 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. For error codes, we use E as a prefix and then upper camel case (also known as Pascal case) for the rest of the name, as seen in EMyErrorCode. The current naming restriction of starting with A to Z is in place to give room for future language features.","breadcrumbs":"Constants » Naming","id":"147","title":"Naming"},"148":{"body":"public or public(package) constants are not currently supported. const values can be used only in the declaring module. However, as a convenience, they can be used across modules in unit tests attributes .","breadcrumbs":"Constants » Visibility","id":"148","title":"Visibility"},"149":{"body":"Currently, constants are limited to the primitive types bool, u8, u16, u32, u64, u128, u256, address, and vector, where T is the valid type for a constant.","breadcrumbs":"Constants » Valid Expressions","id":"149","title":"Valid Expressions"},"15":{"body":"Integer types of one size can be cast to integer types of another size. Integers are the only types in Move that support casting. Casts do not truncate. Casting aborts if the result is too large for the specified type. Syntax Operation Aborts if (e as T) Cast integer expression e into an integer type T e is too large to represent as a T Here, the type of e must be 8, 16, 32, 64, 128 or 256 and T must be u8, u16, u32, u64, u128, or u256. For example: (x as u8) (y as u16) (873u16 as u32) (2u8 as u64) (1 + 3 as u128) (4/2 + 12345 as u256)","breadcrumbs":"Primitive Types » Integers » Casting","id":"15","title":"Casting"},"150":{"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":"150","title":"Values"},"151":{"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! Additionally, constants can refer to other constants within the same module. const BASE: u8 = 4;\nconst SQUARE: u8 = BASE * BASE; Note though, that any cycle in the constant definitions results in an error. const A: u16 = B + 1;\nconst B: u16 = A + 1; // ERROR!","breadcrumbs":"Constants » Complex Expressions","id":"151","title":"Complex Expressions"},"152":{"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 type (that satisfies the specified constraints). This sort of parameterization allows you to reuse the same implementation across multiple types and situations.","breadcrumbs":"Generics » Generics","id":"152","title":"Generics"},"153":{"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":"153","title":"Declaring Type Parameters"},"154":{"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":"154","title":"Generic Functions"},"155":{"body":"Type parameters for structs are placed after the struct name, and can be used to name the types of the fields. public struct Foo has copy, drop { x: T } public 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":"155","title":"Generic Structs"},"156":{"body":"","breadcrumbs":"Generics » Type Arguments","id":"156","title":"Type Arguments"},"157":{"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":"157","title":"Calling Generic Functions"},"158":{"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() { // type arguments on construction let foo = Foo { x: true }; let bar = Bar { x: 0, y: vector[] }; // type arguments on destruction let Foo { x } = foo; let Bar { x, y } = bar;\n} In any case if you do not specify the type arguments, Move's type inference will supply them for you.","breadcrumbs":"Generics » Using Generic Structs","id":"158","title":"Using Generic Structs"},"159":{"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":"159","title":"Type Argument Mismatch"},"16":{"body":"As with the other scalar values built-in to the language, integer values are implicitly copyable, meaning they can be copied without an explicit instruction such as copy .","breadcrumbs":"Primitive Types » Integers » Ownership","id":"16","title":"Ownership"},"160":{"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. module a::m { fun foo() { let v = vector[]; // ERROR! // ^ The compiler cannot figure out the element type, since it is never used let v = vector[]; // ^~~~~ Must annotate manually in this case. }\n} Note that these cases are a bit contrived since the vector[] is never used, ad as such, Move's type inference cannot infer the type. However, the compiler will be able to infer the type if that value is used later in that function: module a::m { fun foo() { let v = vector[]; // ^ is inferred vector::push_back(&mut v, 42); // ^ is inferred }\n}","breadcrumbs":"Generics » Type Inference","id":"160","title":"Type Inference"},"161":{"body":"In Move, the integer types u8, u16, u32, u64, u128, and u256 are all distinct types. However, each one of these types can be created with the same numerical value syntax. In other words, if a type suffix is not provided, the compiler will infer the integer type based on the usage of the value. let x8: u8 = 0;\nlet x16: u16 = 0;\nlet x32: u32 = 0;\nlet x64: u64 = 0;\nlet x128: u128 = 0;\nlet x256: u256 = 0; If the value is not used in a context that requires a specific integer type, u64 is taken as a default. let x = 0;\n// ^ u64 is used by default If the value however is too large for the inferred type, an error will be given let i: u8 = 256; // ERROR!\n// ^^^ too large for u8\nlet x = 340282366920938463463374607431768211454;\n// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ too large for u64 In cases where the number is too large, you might need to annotate it explicitly let x = 340282366920938463463374607431768211454u128;\n// ^^^^ valid!","breadcrumbs":"Generics » Integers","id":"161","title":"Integers"},"162":{"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: public struct Foo { foo: u64\n} This can be convenient when modeling certain concepts. Here is an example: module a::m { // Currency Specifiers public struct A {} public struct B {} // A generic coin type that can be instantiated using a currency // specifier type. // e.g. Coin, Coin etc. public 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_a(value: u64): Coin { mint_generic(value) } public fun mint_b(value: u64): Coin { mint_generic(value) }\n} In this example, 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 generality applies even when the Currency type parameter does not appear in any of the fields defined in Coin.","breadcrumbs":"Generics » Unused Type Parameters","id":"162","title":"Unused Type Parameters"},"163":{"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 A and B 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 storage. One possible solution would be to add spurious ability annotations to A and B (i.e., public 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 value in the storage to have a field in type A, 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. public struct Coin has store { value: u64\n} 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. public struct S1 { f: u64 }\n// ^^^^^^^ valid, T1 does not appear inside the struct definition public struct S2 { f: S1 }\n// ^^^^^^^ valid, T1 appears in phantom position The following code shows examples of violations of the rule: public struct S1 { f: T }\n// ^^^^^^^ ERROR! ^ Not a phantom position public struct S2 { f: T }\npublic struct S3 { f: S2 }\n// ^^^^^^^ ERROR! ^ Not a phantom position 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 . Note that specifying phantom is not required, but the compiler will warn if a type parameter could be phantom but was not marked as such. Instantiation When instantiating a struct, the arguments to phantom parameters are excluded when deriving the struct abilities. For example, consider the following code: public struct S has copy { f: T1 }\npublic struct NoCopy {}\npublic struct 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. public struct S {} When instantiating a phantom type parameter with an ability constraint, the type argument has to satisfy that constraint, even though the parameter is phantom. The usual restrictions apply and T can only be instantiated with arguments having copy.","breadcrumbs":"Generics » Phantom Type Parameters","id":"163","title":"Phantom Type Parameters"},"164":{"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--a type with no abilities . Constraints 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":"164","title":"Constraints"},"165":{"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":"165","title":"Declaring Constraints"},"166":{"body":"Constraints are checked at instantiation sites public struct Foo { x: T } public struct Bar { x: Foo }\n// ^^ valid, u8 has `copy` public struct Baz { x: Foo }\n// ^ ERROR! T does not have 'copy' And similarly for functions fun unsafe_consume(x: T) { // ERROR! x does not have 'drop'\n} fun consume(x: T) { // valid, x will be dropped automatically\n} public struct NoAbilities {} fun foo() { let r = NoAbilities {}; consume(NoAbilities); // ^^^^^^^^^^^ ERROR! NoAbilities does not have 'drop'\n} And some similar examples, but with copy fun unsafe_double(x: T) { (copy x, x) // ERROR! T does not have 'copy'\n} fun double(x: T) { (copy x, x) // valid, T has 'copy'\n} public struct NoAbilities {} fun foo(): (NoAbilities, NoAbilities) { let r = NoAbilities {}; double(r) // ^ ERROR! NoAbilities does not have 'copy'\n} For more information, see the abilities section on conditional abilities and generic types .","breadcrumbs":"Generics » Verifying Constraints","id":"166","title":"Verifying Constraints"},"167":{"body":"","breadcrumbs":"Generics » Limitations on Recursions","id":"167","title":"Limitations on Recursions"},"168":{"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: public struct Foo { x: Foo // ERROR! 'Foo' containing 'Foo'\n} public struct Bar { x: Bar // ERROR! 'Bar' containing 'Bar'\n} // ERROR! 'A' and 'B' forming a cycle, which is not allowed either.\npublic struct A { x: B\n} public struct B { x: A y: A\n}","breadcrumbs":"Generics » Recursive Structs","id":"168","title":"Recursive Structs"},"169":{"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. This restriction might be relaxed in the future, but for now, the following examples should give you an idea of what is allowed and what is not. module a::m { public 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} Not allowed: module a::m { public struct A {} // Infinitely many types -- NOT allowed. // error! // foo -> foo> -> foo>> -> ... fun foo() { foo>(); }\n} And similarly, not allowed: module a::n { public 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} 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. module a::m { public struct A {} // Infinitely many types -- NOT allowed. // error! fun foo(n: u64) { if (n > 0) foo>(n - 1); }\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":"169","title":"Advanced Topic: Type-level Recursions"},"17":{"body":"bool is Move's primitive type for boolean true and false values.","breadcrumbs":"Primitive Types » Bool » Bool","id":"17","title":"Bool"},"170":{"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 storage (as defined by the specific deployment of Move, e.g. the notion of storage for the blockchain). 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). For Sui, key is used to signify an object . Objects are the basic unit of storage where each object has a unique, 32-byte ID. store is then used to both indicate what data can be stored inside of an object, and is also used to indicate what types can be transferred outside of their defining module.","breadcrumbs":"Type Abilities » Abilities","id":"170","title":"Abilities"},"171":{"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 value in storage. For Sui, store controls what data can be stored inside of an object . store also controls what types can be transferred outside of their defining module. key Allows the type to serve as a \"key\" for storage. Ostensibly this means the value can be a top-level value in storage; in other words, it does not need to be contained in another value to be in storage. For Sui, key is used to signify an object .","breadcrumbs":"Type Abilities » The Four Abilities","id":"171","title":"The Four Abilities"},"172":{"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":"172","title":"copy"},"173":{"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":"173","title":"drop"},"174":{"body":"The store ability allows values of types with this ability to exist inside of a value in storage, but not necessarily as a top-level value in storage. This is the only ability that does not directly gate an operation. Instead it gates the existence in storage when used in tandem with key. If a value has store, all values contained inside of that value have store. For Sui, store serves double duty. It controls what values can appear inside of an object , and what objects can be transferred outside of their defining module.","breadcrumbs":"Type Abilities » store","id":"174","title":"store"},"175":{"body":"The key ability allows the type to serve as a key for storage operations as defined by the deployment of Move. While it is specific per Move instance, it serves to gates all storage operations, so in order for a type to be used with storage primitives, the type must have the key ability. If a value has key, all values contained inside of that value have store. This is the only ability with this sort of asymmetry. For Sui, key is used to signify an object .","breadcrumbs":"Type Abilities » key","id":"175","title":"key"},"176":{"body":"All primitive, builtin types have copy, drop, and store. bool, u8, u16, u32, u64, u128, u256, and address all have copy, drop, and store. 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. Note that none of the primitive types have key, meaning none of them can be used directly with storage operations.","breadcrumbs":"Type Abilities » Builtin Types","id":"176","title":"Builtin Types"},"177":{"body":"To declare that a struct or enum has an ability, it is declared with has after the datatype name and either before or after the fields/variants. For example: public struct Ignorable has drop { f: u64 }\npublic struct Pair has copy, drop, store { x: u64, y: u64 }\npublic struct MyVec(vector) has copy, drop, store; public enum IgnorableEnum has drop { Variant }\npublic enum PairEnum has copy, drop, store { Variant }\npublic enum MyVecEnum { Variant } has copy, drop, store; In this case: Ignorable* has the drop ability. Pair* and MyVec* both have 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. An enum can have any of these abilities with the exception of key, which enums cannot have because they cannot be top-level values (objects) in storage. The same rules apply to fields of enum variants as they do for struct fields though. In particular, if an enum is declared with the ability... copy, all fields of all variants must have copy. drop, all fields of all variants must have drop. store, all fields of all variants must have store. key, is not allowed on enums as previously mentioned. For example: // A struct without any abilities\npublic struct NoAbilities {} public struct WantsCopy has copy { f: NoAbilities, // ERROR 'NoAbilities' does not have 'copy'\n} public enum WantsCopyEnum has copy { Variant1 Variant2(NoAbilities), // ERROR 'NoAbilities' does not have 'copy'\n} and similarly: // A struct without any abilities\npublic struct NoAbilities {} public struct MyData has key { f: NoAbilities, // Error 'NoAbilities' does not have 'store'\n} public struct MyDataEnum has store { Variant1, Variant2(NoAbilities), // Error 'NoAbilities' does not have 'store'\n}","breadcrumbs":"Type Abilities » Annotating Structs and Enums","id":"177","title":"Annotating Structs and Enums"},"178":{"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: // public 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 storage only if the inner elements can be in 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":"178","title":"Conditional Abilities and Generic Types"},"179":{"body":"public struct NoAbilities {}\npublic struct S has copy, drop { f: bool }\npublic struct 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":"179","title":"Example: conditional copy"},"18":{"body":"Literals for bool are either true or false.","breadcrumbs":"Primitive Types » Bool » Literals","id":"18","title":"Literals"},"180":{"body":"public struct NoAbilities {}\npublic struct S has copy, drop { f: bool }\npublic struct 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":"180","title":"Example: conditional drop"},"181":{"body":"public struct Cup has copy, drop, store { item: T } // 'MyInnerData is declared with 'store' so all fields need 'store'\nstruct MyInnerData has store { yes: Cup, // Valid, 'Cup' has 'store' // no: Cup, Invalid, 'Cup' does not have 'store'\n} // 'MyData' is declared with 'key' so all fields need 'store'\nstruct MyData 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":"181","title":"Example: conditional store"},"182":{"body":"public struct NoAbilities {}\npublic struct MyData has key { f: T } fun valid(addr: address) acquires MyData { // Valid, 'MyData' has 'key' transfer(addr, MyData { f: 0 });\n} fun invalid(addr: address) { // Invalid, 'MyData' does not have 'key' transfer(addr, MyData { f: NoAbilities {} }) // Invalid, 'MyData' does not have 'key' borrow(addr); // Invalid, 'MyData' does not have 'key' borrow_mut(addr);\n} // Mock storage operation\nnative public fun transfer(addr: address, value: T);","breadcrumbs":"Type Abilities » Example: conditional key","id":"182","title":"Example: conditional key"},"183":{"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":"183","title":"Uses and Aliases"},"184":{"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::option as o; 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::option as o; would let you use o instead of std::option use std::vector;\nuse std::option as o; fun new_vec(): vector> { let mut v = vector[]; vector::push_back(&mut v, o::some(0)); vector::push_back(&mut v, o::none()); v\n} If you want to import a specific module member (such as a function or struct). You can use the following syntax. use ::::;\nuse :::: as ; For example use std::vector::push_back;\nuse std::option::some as s; This would let you use the function std::vector::push_back without full qualification. Similarly for std::option::some with s. Instead you could use push_back and s respectively. Again, use std::vector::push_back; is equivalent to use std::vector::push_back as push_back; use std::vector::push_back;\nuse std::option::some as s; fun new_vec(): vector> { let mut v = vector[]; vector::push_back(&mut v, s(0)); vector::push_back(&mut v, std::option::none()); v\n}","breadcrumbs":"Uses and Aliases » Syntax","id":"184","title":"Syntax"},"185":{"body":"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;\nuse std::option::{some as s, none as n}; fun new_vec(): vector> { let mut v = vector[]; push_back(&mut v, s(0)); push_back(&mut v, n()); v\n}","breadcrumbs":"Uses and Aliases » Multiple Aliases","id":"185","title":"Multiple Aliases"},"186":{"body":"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::option::{Self, some, none}; For clarity, all of the following are equivalent: use std::option;\nuse std::option as option;\nuse std::option::Self;\nuse std::option::Self as option;\nuse std::option::{Self};\nuse std::option::{Self as option};","breadcrumbs":"Uses and Aliases » Self aliases","id":"186","title":"Self aliases"},"187":{"body":"If needed, you can have as many aliases for any item as you like use std::vector::push_back;\nuse std::option::{Option, some, none}; fun new_vec(): vector