solidity中reference type

本文详细介绍了Solidity编程语言中的6种引用类型:struct、array、mapping、enum、immutable&constant以及string。通过实例展示了如何声明、初始化、操作这些类型,并探讨了它们在智能合约中的应用,特别是struct在映射和数组中的使用,以及enum的规则设定。此外,还提到了在返回结构体时需要注意的编码问题和稳定性考虑。最后,通过一个CRUD合约展示了这些概念的实际运用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

solidity中6种reference type:
1.struct
2.array
3.map
4.enum
5.immutable &constant // 不可变常量
6.string
is same? 首字母缩写

一.stuct
多维的结构,结构体内还可以再包含字符串,整型,映射,结构体等复杂类型

1.设置struct 名称A
struct A{
string title;
string author;
uint book_id;
}
2.声明变量一样,声明一个变量book,指定类型为刚刚设置的struct名字A
A book;
3.写入book = A(‘’, ‘’, 1) //按照struct传参
// 第一种
book.push(A(titlename, ‘TP’, 1));
// 第二种
book.push(A({
title:titlename,
author: ‘dhk’,
book_id:2
}));
// 第三种
A memory mybook;
mybook.title = titlename;
mybook.author = ‘newauthor’;
mybook.book_id = 3;
book.push(mybook);

4.读取book.book_id

pragma solidity ^0.5.0;
contract test {
   struct A{
      string title;
      string author;
      uint book_id;
   }
   A book;
   function setBook() public {
      book = A('Learn Java', 'TP', 1);
   }
   function getBookId() public view returns (uint) {
      return book.book_id;
   }
}

在返回结构体的情况下,编码需要注意添加“pragma experimental ABIEncoderV2;”,需要注意的是结构体中也不能包含string/bytes等不定长数据类型,但是返回struct这种形式还处于试验阶段,稳定性安全性有待论证。

pragma solidity ^0.4.17;

pragma experimental ABIEncoderV2;

contract  Test{

    struct MyStruct { int key; uint deleted; }

function TTest() returns() {

   return MyStruct({key:int(1),deleted:uint(1)});

    }

}

二、数组[]
我们了解了数据位置的工作方式以及何时可以使用以下三个位置:memory,storage和calldata。
1.Storage arrays,状态存储数组,动态存储数组可以调整数组的大小,它们通过访问push()和pop()方法来调节长度。

uint [] name;
// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

contract A {
      uint256[] public numbers;// 动态长度数组
      address[10] private users; // 固定长度数组
      uint8 users_count;
      
      function addUser(address _user) external {
          require(users_count < 10, "number of users is limited to 10");
          users[users_count] = _user;
          users_count++;
      }
      
      function addNumber(uint256 _number) external {
          numbers.push(_number);
      }
}

2.内存数组
但是不能调整动态大小的内存数组的大小(即,不能调用push()和pop()方法),数组的大小必须预先计算。声明方法和状态存储数组不一样:

Type[] memory a = new Type[](size)

1.设置数组类型:
2.数组和struct结合

pragma solidity ^0.5.0;
contract test {
   struct A {
      string title;
      string author;
      uint book_id;
   }
   A[] public book; //定义数组book,里面类型是A
   function setBook(string memory titlename) public {
   // 第一种
      book.push(A(titlename, 'TP', 1)); 
    //   第二种
    book.push(A({
        title:titlename,
        author: 'dhk',
        book_id:2
    })); 
        // 第三种
    A memory mybook;
    mybook.title = titlename;
    mybook.author = 'newauthor';
    mybook.book_id = 3;
    book.push(mybook);
   }
   function getBookId() public view returns (string memory) {
      return book[1].author;
   }
}

三、mapping
mapping(key_type=> value_type) public A;
把struct放进map里面,一维对象放进多维对象。

pragma solidity ^0.5.0;
contract Store{

    struct Product{
        uint productId;
        uint productValue;
    }
    
    mapping (uint=>Product) products;
    
    function save() public {
        Product  memory product = Product(2,93);
        products[120]=product;
    }

    function getPriceOfProductId(uint productId) public view returns (uint){  
        return products[productId].productValue;
    }
}

四、enum
一维的
枚举类型,定好规则,到里面取。类型到咖啡厅,定好大中小杯。方便客户。

pragma solidity ^0.5.0;
contract Enumtest {
   enum FreshJuiceSize{ SMALL, MEDIUM, LARGE } // 对应的:0,1,2
   FreshJuiceSize choice;
   FreshJuiceSize constant defaultChoice = FreshJuiceSize.MEDIUM;
   function setLarge() public {
      choice = FreshJuiceSize.LARGE; // 返回2
   }
   function getChoice() public view returns (FreshJuiceSize) {
      return choice;
   }
   function getDefaultChoice() public pure returns (uint) {
      return uint(defaultChoice); // 返回1
   }
}

五、immutable&constant
constant只能定义值类型和string类型
对于constant,该值必须在编译时确定,而对于immutable,则是在构造时赋值。
uint256 constant maxParticipants = 10;

contract C {
      address immutable owner = msg.sender;
      uint256 immutable maxBalance;
    
      constructor(uint256 _maxBalance){
           maxBalance = _maxbalance;
      }
}

六、string
一维的
Solidity提供字节与字符串之间的内置转换,可以将字符串赋给 byte32类型变量。

pragma solidity ^0.5.0;
contract SolidityTest {
   string data = "test";
   bytes32 data2 = "test"; // 把string隐式转为bytes32
   function mydata() public pure {
       bytes memory bstr = new bytes(10);
       string memory message = string(bstr); // 显式转为string
   }
}

总结:运用上面的知识,做一个crud增删改查合约

// SPDX-License-Identifier: MIT

pragma solidity ^0.7.0;

contract Crud {
    
    struct User {
        uint256 id;
        string name;
    }
    
    User[] public users;
    uint256 public nextId = 1;
    
    function add(string memory name) public {
        User memory user = User({id : nextId, name : name});
        users.push(user);
        nextId++;
    }
    
    function read(uint256 id) public view returns(string memory){
        uint256 i = find(id);
        return users[i].name;
    }
    
    function update(uint256 id, string memory newName) public {
        uint256 i = find(id);
        users[i].name = newName;
    }
    
    function destroy(uint256 id) public {
        uint256 i = find(id);
        delete users[i];
    }
    
    function find(uint256 id) private view returns(uint256){
        for(uint256 i = 0; i< users.length; i++) {
            if(users[i].id == id)
                return i;
        }
        revert("User not found");
    }
    
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端段

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值