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");
}
}