Solidity之Mappings篇

Posted 师薄零

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Solidity之Mappings篇相关的知识,希望对你有一定的参考价值。

关于Mappings

Solidity中Mappings 的概念类似于java中的hashmap或者python中的dictionnary。它们使用都起来有一点像hash表,

尽管它们在以下方面略有不同:

在solidity中所有可能的变量都以默认值初始化。

正因为如此, mappings是没有长度的。没有设置一个key或者value的概念。关键数据不是储存在一个mapping中的,相反的它的keccak256 hash值用来存储关键数据指向的value值。

如何来定义一个Mapping?

mapping (_KeyType => _ValueType) mappingName;

一个好建议:在mapping变量名之前使用public关键字。这将会自动为mapping创建一个getter方法。你只需要通过传入_KeyType参数给getter就能返回_ValueType.

mapping (_KeyType => _ValueType) public mappingName;

如何使用一个mapping?

  • 对关联关系非常有用,就像将一个eth的地址和一个uint的整数关联起来 mapping(address => _valueType) my_mapping
  • mapping(uint => _valueType) my_mapping

举个例子在游戏中我们把玩家的地址和玩家的等级关联起来

mapping(address => uint) public userLevel;

另一个例子列出地址是否能够发送eth?

mapping(address => bool) allowedToSend;

另外一个例子mapping的value值是一个struct类型。

struct someStruct 

mapping(uint => someStruct) canDoSomething;

uint canDoSomethingKey = 0;

function addCanDoSomething() 
     canDoSomething[canDoSomethingKey] = someStruct(arg1, arg2, ...);
     canDoSomethingKey++;

如何从Mapping中获得value值?

function currentLevel(address userAddress) public view returns (uint) 
     return userLevel[userAddress];

使用Mapping作为另一个Mapping的value值

contract C 
    struct S  uint a; uint b; 
    uint x;
    mapping(uint => mapping(uint => S)) data;

循环一个mapping?

因为开头所说的原因不能直接去循环一个mapping变量。

mappings are virtually initialised such that every possible key exists and is mapped to a value

然而可以实现一个基于mapping之上的数据结构,来使得mapping可以被循环。

可以记录一个counter的计数器,来告诉你mapping的长度当有新增的value值的时候。

Mappings作为函数的参数

这是一个比较难得主题,但是我们还是尝试去探讨一下。Mappings可以作为参数传到函数中,但是它们必须满足下面的2个要求:

  1. Mappings只能作为内部和私有函数的参数
  2. Mappings作为参数传递时,数据的存储位置只能是storage

你不能使用Mappings的地方

  • 不能直接循环mapping类型
  • Mappings在solidity中参数不能作为参数传递到公有函数和外部函数
  • Mappings不能作为函数的返回值
Variable TypeKey TypeValue Type
int / uint✔️✔️
string✔️✔️
byte / bytes✔️✔️
address✔️✔️
struct✔️
mapping✔️
enum✔️
contract✔️
* fixed-sized array T[k]✔️✔️
* dynamic-sized array T[]✔️
* multi-dimentional array T[][]✔️
variable

## github仓库 
<https://github.com/coffiasd/solidity-learn>

第151篇 Solidity 中的数组(Array)

solidity 中的数组(Array)大小可以是固定的,也可以是动态的;

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

contract Array 
    // Several ways to initialize an array
    uint[] public arr;
    uint[] public arr2 = [1, 2, 3];
    // Fixed sized array, all elements initialize to 0
    uint[10] public myFixedSizeArr;

    function get(uint i) public view returns (uint) 
        return arr[i];
    

    // Solidity can return the entire array.
    // But this function should be avoided for
    // arrays that can grow indefinitely in length.
    function getArr() public view returns (uint[] memory) 
        return arr;
    

    function push(uint i) public 
        // Append to array
        // This will increase the array length by 1.
        arr.push(i);
    

    function pop() public 
        // Remove last element from array
        // This will decrease the array length by 1

以上是关于Solidity之Mappings篇的主要内容,如果未能解决你的问题,请参考以下文章

区块链开发之Solidity编程基础

区块链2.0以太坊智能合约solidity之helloworld

Solidity之Mappings篇

区块链开发之Solidity编程基础合约事件

区块链开发之Solidity编程基础合约事件

区块链开发之Solidity编程基础