Join our
Discord!
LogoLogo
SupraScan ExplorerStarKey WalletDiscord
MoveVM
  • Network
  • Oracles
  • Automation
  • SupraNova
  • Guides
MoveVM
  • Overview
  • Getting Started
    • Install Supra CLI with Docker
    • Create a Supra Account
    • Create a Move Package
      • Initialize a Package
      • Write a Module
      • Compile and Publish
      • Interact with a Package
    • Create a dApp with StarKey
  • Network Information
  • Token Standards
  • Learn Move 101
    • Getting Started with Move
    • Unsigned Integers in Move
    • Math Operations in Move
    • Using Vectors in Move
    • Reading Resource Data with borrow_global
    • Passing Data in Move: Value vs. Reference
    • Adding Elements with vector::push_back
    • Emitting Events with event::emit
  • Move Book
    • Getting Started
      • Modules and Scripts
      • Move Tutorial
    • Primitive Types
      • Integers
      • Bool
      • Address
      • Vector
      • Signer
      • References
      • Tuples and Unit
    • Basic Concepts
      • Local Variables and Scope
      • Equality
      • Abort and Assert
      • Conditionals
      • While, For, and Loop
      • Functions
      • Structs and Resources
      • Constants
      • Generics
      • Type Abilities
      • Uses and Aliases
      • Friends
      • Packages
      • Package Upgrades
      • Unit Tests
    • Global Storage
      • Structure
      • Operators
    • Reference
      • Standard Library
      • Coding Conventions
  • TypeScript SDK
    • Guides
      • Create Supra Accounts
      • Publish a Package
    • Documentation
    • Repository
  • Rest API
    • Mainnet
      • Accounts
      • Faucet
      • Transactions
      • Block
      • View
      • Consensus
      • Events
      • Tables
    • Testnet
      • Accounts
      • Faucet
      • Transactions
      • Block
      • View
      • Events
      • Tables
  • Developer Resources
    • Supra Dapp Templates
    • Supra Move VS Code Extension
  • Links
    • Supra DevHub
    • SupraScan Block Explorer
    • StarKey Wallet
    • Live Data Feeds
    • Whitepapers
    • Security Audits
    • Supra's Official GitHub
Powered by GitBook
On this page
Edit on GitHub
  1. Learn Move 101

Passing Data in Move: Value vs. Reference

Move uses pass-by-value for copies and pass-by-reference (& for reading, &mut for modifying) to data handling.

PreviousReading Resource Data with borrow_globalNextAdding Elements with vector::push_back

For the latest RPC URL, please refer to the page.

pass-by-value & pass-by-reference

In Move, when you pass a simple value as u64 to a function, you might be making a copy of it. This is called pass-by-value, for example:

fun add_one(value: u64) {
    // This doesn't change the original value!
    value = value + 1;
}

fun call_add_one() {
    let value = 10;
    // This is wrong as it makes a copy of value!
    add_one(value);

    // This will error out as the value is still 10!
    assert!(value == 11, 0);
}

So how do we modify the original value?

We need to pass a mut reference (&mut) to the value instead of the value itself. This is called pass-by-reference. This is similar to how you pass a pointer to a value in C/C++ or Rust.

There are two types of references in Move: references (&) and mutable references (&mut). The immutable reference (&) is often used to pass a value such as a vector to a function that only intends to read data instead of writing it. A function that takes a reference needs to explicitly declare:

// get_first_element takes a reference to a vector and returns the first element.

fun get_first_element(values: &vector<u64>): u64 {
    // vector::borrow also takes a vector reference and returns a reference to the value.
    // * is needed here to dereference the value and make a copy of it to return.
    *vector::borrow(values, 0)
}

You can also pass a reference to a struct and modify it:

struct Balance {
    value: u64,
}

// This would fail if the function takes &Balance instead of &mut Balance.
fun double_balance(balance: &mut Balance): u64 {
    balance.value = balance.value * 2;
}

Now, Write a function in Dinosaur_nest that returns the Gendna of the first Dinosaur in the DinosaurSwarm. Don’t forget the “acquires” declaration!

module 0xcafe::Dinosaur_nest {
    use std::vector;

    struct DinosaurGendna has key {
        Gendna_digits: u64,
        Gendna_modulus: u64,
    }

    struct Dinosaur has store {
        Gendna: u64,
    }

    struct DinosaurSwarm has key {
        Dinosaurs: vector<Dinosaur>,
    }

    fun init_module(cafe_signer: &signer) {
        let Gendna_digits = 10;
        let Gendna_modulus = 10 ^ Gendna_digits;
        move_to(cafe_signer, DinosaurGendna {
            Gendna_digits,
            Gendna_modulus: (Gendna_modulus as u256),
        });
        move_to(cafe_signer, DinosaurSwarm {
            Dinosaurs: vector[],
        });
    }

    public fun spawn_Dinosaur(Gendna: u64): Dinosaur {
        Dinosaur {
            Gendna,
        }
    }

    public fun get_Gendna_digits(): u64 acquires DinosaurGendna {
        borrow_global<DinosaurGendna>(@0xcafe).Gendna_digits
    }

    public fun set_Gendna_digits(new_Gendna_digits: u64) acquires DinosaurGendna {
        let Dinosaur_Gendna = borrow_global_mut<DinosaurGendna>(@0xcafe);
        Dinosaur_Gendna.Gendna_digits = new_Gendna_digits;
    }

public fun get_first_Dinosaur_Gendna(): u64 acquires DinosaurSwarm {
        let Dinosaur_swarm = borrow_global<DinosaurSwarm>(@0xcafe);    
        let first_Dinosaur = vector::borrow(&Dinosaur_swarm.Dinosaurs, 0);
        first_Dinosaur.Gendna        
  }
}
Supra Network Information