上期主要介绍了一些数据类型,这期继续详细介绍数据类型的使用
一、定长的字节数组solidity内置了⼀些数组的数据类型:
bytes1 , … , bytes32 ,允许值以步⻓1递增。byte默认表示bytes1,byte是类型,bytes是类型,bytes1是内置数组bytes1只能存储1个字节,即8位的内容,bytes2最多只能存储2个字节,即16位的内容。以此类推…读取⻓度 length⻓度不可以修改可以通过下标访问内容不可修改pragma solidity ^0.4.2;
//bytes1
contract fixedArray {
/*
1. ⻓度可以读取 length
2. ⻓度不可以修改
3. 可以通过下标访问
4. 内容不可修改
*/
//bytes1 ... bytes32
//bytes1 b1 = "xy";
bytes2 b2 = "xy";
bytes3 public b3 = "xy";
uint public len = b3.length;
//b3.length = 10;
bytes8 b8 = "12345678";
//b8_0返回0x31,即⼗进制的数字1的ascii值(3*16+1=49)
bytes1 public b8_0 = b8[0];
//b = "HELLO";ERROR,定义之后不可修改
//b8[1] = "0";
//b8= "4567";
}
动态大小的字节数组
bytes : 动态⻓度的字节数组(⾮值类型)
string : 动态⻓度的UTF-8编码的字符类型(⾮值类型)
⼀个好的使⽤原则是: bytes⽤来存储任意⻓度的字节数据,string⽤来存储任意⻓度的UTF-8编码 的
字符串数据。 如果⻓度可以确定,尽量使⽤定⻓的如byte1到byte32中的⼀个,因为这样更省空间。
pragma solidity ^0.4.24;
contract Test {
bytes public name;
function getLen() public view returns(uint256) {
return name.length;
}
//1. 可以不分空间,直接进行字符串赋值,会自动分配空间
function setValue(bytes input) public {
name = input;
}
//2. 如果未分配过空间,使用下标访问会访问越界报错
function getByIndex(uint256 i) public view returns(byte) {
return name[i];
}
//3. 可以设置长度,自动分配对应空间,并且初始化为0
function setLen(uint256 len) public {
name.length = len;
}
//4.可以通过下标进行数据修改
function setValue2(uint256 i) public {
name[i] = 'h';
}
//5. 支持push *** 作,在bytes最后面追加元素
function pushData() public {
name.push('h');
}
}
字符串string
动态尺寸的UTF-8编码字符串,是特殊的可变字节数组引用类型不支持下标索引不支持length、push方法可以修改(需通过bytes转换)
pragma solidity ^0.4.24;
contract Test {
string public name = "lily";
function setName() public {
bytes(name)[0] = "L";
}
function getLength() public view returns(uint256) {
return bytes(name).length;
}
function setLength(uint256 i) public {
bytes(name).length = i;
bytes(name)[i - 1] = 'H';
}
}
三、转换(byte1/bytes/string)
pragma solidity ^0.4.24;
contract Test {
bytes10 b10 = 0x68656c6c6f776f726c64; //helloworld
//bytes bs10 = b10; //⽆法直接转换
bytes public bs10 = new bytes(b10.length);
//1. 固定字节数组转动态字节数组
function fixedBytesToBytes() public{
for (uint i = 0; i< b10.length; i++){
bs10[i] = b10[i];
}
}
//2.string转动态字节数组
string greeting = "helloworld";
bytes public b1;
function StringToBytes() public {
b1 = bytes(greeting);
}
//3. 动态字节数组转string
string public str3;
function BytesToString() public {
fixedBytesToBytes();
str3 = string(bs10);
}
//4. fixed bytes to String,error
function FiexBytesToString(){
//string tmp = string(b10);
}
}
四、数组
内置数组(已介绍)
string(不定⻓)bytes(不定⻓)bytes1…bytes32(定⻓)
自定义数组
自定义定长数组
类型T,⻓度K的数组定义为T[K],例如:uint [5] numbers, byte [10] names;内容可变⻓度不可变,不⽀持push⽀持length⽅法
pragma solidity ^0.4.5;
contract test {
//test1:
uint[10] value = [1,2,3,4,5];
uint public sum;
function getSum(){
sum = 0;
for (uint i = 0; i < value.length; i++){
sum += value[i];
}
}
function changeValue(){
value[0] = 2; //内容可修改
//value.length = 100; //报错,⻓度不可修改
}
}
不定⻓数组
定义格式为T [ ],例如:string[ ] names, byte[ ] citys。内容可以修改可以改变⻓度(仅限storage类型) ⽀持 length 、 push ⽅法memory类型的不定⻓数组不⽀持修改⻓度
pragma solidity ^0.4.24;
contract Test {
//第一种创建方式,直接赋值
uint8[] numbers = [1,2,3,4,5,6,7,8,9,10];
function pushData(uint8 num) public {
numbers.push(num);
}
function getNumbers() public view returns(uint8[]) {
return numbers;
}
//使用new关键字进行创建,赋值给storage变量数组
uint8[] numbers2;
function setNumbers2() public {
numbers2 = new uint8[](7);
numbers2.length = 20;
numbers2.push(10);
}
function getNumbers2() public view returns(uint8[]) {
return numbers2;
}
function setNumbers3() public {
//使用new创建的memory类型数组,无法改变长度
//uint8[] memory numbers3 = new uint8[](7);
uint8[] memory numbers3;
//numbers3.push(10);
}
}
五、结构体
pragma solidity ^0.4.5;
contract Test {
//定义结构之后⽆分号,与枚举⼀致
struct Student {
string name;
uint age;
uint score;
string sex;
}
Student[] public Students;
//两种赋值⽅式
Student public stu1 = Student("lily", 18, 90, "girl");
Student public stu2 = Student({name:"Jim", age:20, score:80,
sex:"boy"});
function assign() public {
Students.push(stu1);
Students.push(stu2);
stu1.name = "Lily";
}
}
六、字典/映射/hash表(mapping)
键key的类型允许除映射外的所有类型,如数组,合约,枚举,结构体,值的类型⽆限制。⽆法判断⼀个mapping中是否包含某个key,因为它认为每⼀个都存在,不存在的返回0或false。映射可以被视作为⼀个哈希表,在映射表中,不存储键的数据,仅仅存储它的 keccak256 哈希值,⽤来查找值时使⽤。映射类型,仅能⽤来定义状态变量,或者是在内部函数中作为storage类型的引⽤。不⽀持lengthkey不⽀持string 类型
pragma solidity ^0.4.20;
contract Test {
//id -> name
mapping(uint => string) public id_names;
//构造函数:
//1. 对象在创建的时候,自动执行的函数,完成对象的初始化工作
//2. 构造函数仅执行一次
// function Test() public {
// }
constructor() public{
id_names[1] = "lily";
id_names[2] = "Jim";
id_names[3] = "Lily";
id_names[3] = "Tom";
}
function getNameById(uint id) public returns (string){
//加上storage如何赋值?
string memory name = id_names[id];
return name;
}
function setNameById(uint id) public returns (string){
// mapping(uint => string) memory id_name = id_names;
// var ids = id_names;
id_names[id] = "Hello";
}
// function getMapLength() public returns (uint){
// return id_names.length;
// }
}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)