solidity基础-引用类型

数据和变量

  • Solidity 是一种静态强类型的语言
  • 变量类型和需要赋值的数据类型必须匹配,或者所赋值的数据可以隐式转换为变量类型

两种类型的数据

值类型

  • 值类型传值时会将值拷贝一份,传递的是值本身
  • 始终按值来传递

引用类型

  • 引用类型进行传递时,传递的是其指针
  • 引用类型进行传递时,可以为值传递,也可以为引用传递
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    uint256 public u = 123;
    string public str1 = "b00l";
    string public str2 = "b00l";
  
    function test() external {

        // 修改值类型
        uint256 x = u;
        x = 1;

        // 修改引用类型,引用传递
        string storage str3 = str1;
        bytes(str3)[0] = bytes1("B"); // str1 的值变为 B00l

        // 修改引用类型,值传递
        string memory str4 = str2;
        bytes(str4)[0] = bytes1("B"); // str2 的值不变
    }
}

引用类型

Array

  • 创建
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    // 固定长度数组创建
    uint256[5] public arrInt = [1, 2, 3, 4, 5]; // [1, 2, 3, 4, 5]
    uint256[5] public arrInt2 = [1]; // [1, 0, 0, 0, 0]
    address[1] public arrAddress = [0x5B38Da6a701c568545dCfcB03FcB875f56beddC4];
    uint256[5] public arrInt3;

    // 可变长度数组
    uint256[] public arrInt4 = [1, 2, 3, 4, 5]; // 不能在函数内创建
    uint256[] arrInt5 = new uint256[](5); // 可以在函数内创建,如果 memory 的时候,不能用 push 方法

    // 内存中创建数组
    function test1() public pure returns (uint256[] memory) {
        uint256[] memory arrInt6 = new uint256[](5);
        arrInt6[0] = 1;
        return arrInt6;
    }

    // 二维数组的创建
    uint256[2][2] public arrInt7 = [[1, 2], [3, 4]];

}

动态数组比定长数组更废 gas

  • 访问和修改数组元素
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    uint256[] arr = [1, 2, 3];

    function test1() external view returns (uint256) {
        return arr[0];
    }

    function test2() external {
        arr[0] = 2;
    }

}
  • 函数中返回整个数组
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    uint256[] arr = [1, 2, 3];

    function test1() external view returns (uint256[] memory) {
        return arr;
    }

}
  • 数组常量
  • 数组的属性

    • length:获取数组长度(只读)
  • 数组的方法

    • push
    • pop
    • delete,用在数组元素表示重置数组元素,长度不变。用在整个数组表示将数组长度置为零
    • name[n: m]:切片
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    uint256[] arr = [1, 2, 3];

    function getArr() external view returns (uint256[] memory) {
        return arr;
    }

    function testPush() external {
        arr.push(9);
    }

    function testPop() external {
        arr.pop();
    }

    function testDel1() external {
        delete arr[0];
    }

    function testDel2() external {
        delete arr;
    }

}
  • 模拟切片的 slice 方法
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    function slice(
        uint256[] memory arr_,
        uint256 begin,
        uint256 end
    ) public pure returns (uint256[] memory) {
        require(begin < end, "index error");
        uint256[] memory tmp = new uint256[](end - begin);
        for (uint256 index = begin; index < end; index++) {
            tmp[begin - index] = arr_[index];
        }
        return tmp;
    }

    function test() external pure returns (uint256[] memory res) {
        uint256[] memory arr = new uint256[](5);
        res = slice(arr, 1, 2);
    }

}
  • delete 完全删除数组的指定索引
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {
    function deletePro(uint256[] memory arr_, uint256 index_)
        internal
        pure
        returns (uint256[] memory tmp)
    {
        require(index_ < arr_.length, "index error");
        tmp = new uint256[](arr_.length - 1);
        for (uint256 i = 0; i < tmp.length; i++) {
            if (i >= index_) {
                tmp[i] = arr_[i + 1];
            } else {
                tmp[i] = arr_[i];
            }
        }
    }

    uint256[] arr = [1, 2, 3, 4, 5];

    function test() external view returns (uint256[] memory) {
        return deletePro(arr, 1);
    }

}

bytes

  • 创建
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {
    // 方式一
    bytes public test1 = bytes("b00l"); // 0x6230306c
    // 方式二
    bytes public test2 = hex"6230306c"; //0x6230306c
    // 方式三
    bytes public test3 = new bytes(2); // 0x0000
    // 方式四 在函数内部创建
    function fun1() external pure returns (bytes memory) {
        bytes memory tmp = new bytes(2);
        return tmp; // 0x0000
    }
}
  • bytes / bytes32 / bytes32[] 的区别

    • bytes:可变字节数组,引用类型
    • bytes32:固定长度字节数组,值类型
    • bytes32[]:由固定长度字节数组组成的数组
  • 属性

    • length:获取长度
    • name[index]:获取指定index下标的数据
  • 方法

    • contact:拼接bytes,返回值是bytes
    • push
    • pop
    • delete
    • name[n, m]:切片

string

  • 格式

    • 成对双引号或单引号包裹
  • 属性

    • 长度:注意,要先转成bytes类型才可获取长度
    • 索引:需要先转成bytes才能获取指定索引的值
  • string 和 bytes / bytesN 之间的转换

bytes 转 string

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

contract Demo {

    bytes public bt1 = bytes("b00l"); // 6230306c
    bytes4 public bt2 = bytes4("b00l"); // 6230306c

    // 动态大小字节数组 => string
    function trans1() external pure returns (string memory) {
        bytes memory bstr = new bytes(2); // 函数内构建
        bstr[0] = "a";
        bstr[1] = "b";
        return string(bstr); // ab
    }

    // 固定长度字节数组 => [动态大小字节数组] => string
    function trans2() external pure returns (string memory) {
        bytes4 bstr = 0x6230306c;
        bytes memory tmp = new bytes(bstr.length);
        for (uint256 i = 0; i < bstr.length; i++) {
            tmp[i] = bstr[i];
        }
        return string(tmp);
    }

}

string 转 bytes

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

contract Demo {

    string str = "b00l";
    function trans1() external view returns (bytes memory) {
        return bytes(str); // 0x6230306c
    }

}

mapping

  • 概念:mapping(映射)是一种引用类型,存储键值对。
  • 创建
    // 创建mapping,第一个 string 约束键的类型,第二个 string 约束值的类型
    mapping(string => string) public test;
  • 获取-设置-删除
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    // 创建mapping,第一个 string 约束键的类型,第二个 string 约束值的类型
    mapping(string => string) m;

    // 获取mapping
    function getvalue() external view returns (string memory) {
        return m["name"];
    }

    // 设置mapping
    function setValue() external {
        m["name"] = "b00l";
    }

    // 删除mapping
    function delValue() external {
        delete m["name"];
    }
    
}

struct

struct(结构体) 是solidity 中的自定义类型,其中可以包含整型、字符串、映射、结构体等复杂类型

  • 创建 struct
struct BaseInfo {
    string name;
    uint8 age;
}
  • 创建实例
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    // 创建struct
    struct BaseInfo {
        string name;
        uint8 age;
    }

    // 实例化struct
    BaseInfo public b00l = BaseInfo("b00l", 18);
    // 或者
    BaseInfo public b00l = BaseInfo({name: "b00l", age: 18});

}
  • 读取、修改、删除
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

contract Demo {

    // 创建struct
    struct BaseInfo {
        string name;
        uint8 age;
    }

    // 实例化 struct
    BaseInfo public b00l = BaseInfo("b00l", 18);

    // 实例化 struct
    function setStruct() external pure returns (BaseInfo memory) {
        BaseInfo memory b00l2 = BaseInfo("b00l2", 20);
        return b00l2;
    }

    // 读取 struct
    function getName() external view returns (string memory) {
        return b00l.name; // b00l
    }

    // 修改 struct
    function resetStruct() external {
        b00l.age = 20;
    }

    // 删除 struct
    function delStruct() external {
        delete b00l;
    }

}

本文链接:

https://www.55geek.cn/index.php/archives/127/
1 + 3 =
快来做第一个评论的人吧~