最新内容会更新在主站深入浅出区块链社区
原文链接:智能合约语言 Solidity 教程系列5 - 数组介绍

写在前面

Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对以太坊、智能合约有所了解,
如果你还不了解,建议你先看以太坊是什么

本文前半部分是参考Solidity官方文档(当前最新版本:0.4.20)进行翻译,后半部分对官方文档中没有提供代码的知识点补充代码说明(订阅专栏阅读)。

数组(Arrays)

数组可以声明时指定长度,也可以是动态变长。对storage存储的数组来说,元素类型可以是任意的,类型可以是数组,映射类型,结构体等。但对于memory的数组来说。如果作为public函数的参数,它不能是映射类型的数组,只能是支持ABI的类型。

一个元素类型为T,固定长度为k的数组,可以声明为T[k],而一个动态大小(变长)的数组则声明为T[]
还可以声明一个多维数组,如声明一个类型为uint的数组长度为5的变长数组(5个元素都是变长数组),可以声明为uint[][5]。(注意,相比非区块链语言,多维数组的长度声明是反的。)

要访问第三个动态数组的第二个元素,使用x[2][1]。数组的序号是从0开始的,序号顺序与定义相反。

bytesstring是一种特殊的数组。bytes类似byte[],但在外部函数作为参数调用中,bytes会进行压缩打包。string类似bytes,但不提供长度和按序号的访问方式(目前)。
所以应该尽量使用bytes而不是byte[]

可以将字符串s通过bytes(s)转为一个bytes,可以通过bytes(s).length获取长度,bytes(s)[n]获取对应的UTF-8编码。通过下标访问获取到的不是对应字符,而是UTF-8编码,比如中文编码是多字节,变长的,所以下标访问到的只是其中的一个编码。
类型为数组的状态变量,可以标记为public,从而让Solidity创建一个访问器,如果要访问数组的某个元素,指定数字下标就好了。(稍后代码事例)

创建内存数组

可使用new关键字创建一个memory的数组。与stroage数组不同的是,你不能通过.length的长度来修改数组大小属性。我们来看看下面的例子:

pragma solidity ^0.4.16;contract C {function f(uint len) public pure {uint[] memory a = new uint[](7);//a.length = 100;  // 错误bytes memory b = new bytes(len);// Here we have a.length == 7 and b.length == lena[6] = 8;}
}

数组常量及内联数组

数组常量,是一个数组表达式(还没有赋值到变量)。下面是一个简单的例子:

pragma solidity ^0.4.16;contract C {function f() public pure {g([uint(1), 2, 3]);}function g(uint[3] _data) public pure {// ...}
}

通过数组常量,创建的数组是memory的,同时还是定长的。元素类型则是使用刚好能存储的元素的能用类型,比如[1, 2, 3],只需要uint8即可存储,它的类型是uint8[3] memory

由于g()方法的参数需要的是uint(默认的uint表示的其实是uint256),所以需要对第一个元素进行类型转换,使用uint(1)来进行这个转换。

还需注意的一点是,定长数组,不能与变长数组相互赋值,我们来看下面的代码:

//  无法编译
pragma solidity ^0.4.0;contract C {function f() public {// The next line creates a type error because uint[3] memory// cannot be converted to uint[] memory.uint[] x = [uint(1), 3, 4];}
}

已经计划在未来移除这样的限制。当前因为ABI传递数组还有些问题。

成员

length属性

数组有一个.length属性,表示当前的数组长度。storage的变长数组,可以通过给.length赋值调整数组长度。memory的变长数组不支持。
不能通过访问超出当前数组的长度的方式,来自动实现改变数组长度。memory数组虽然可以通过参数,灵活指定大小,但一旦创建,大小不可调整。

push方法

storage的变长数组和bytes都有一个push方法(string没有),用于附加新元素到数据末端,返回值为新的长度。

限制情况

当前在external函数中,不能使用多维数组。

另外,基于EVM的限制,不能通过外部函数返回动态的内容。

contract C {function f() returns (uint[]) { ... }}

在这个的例子中,如果通过web.js调用能返回数据,但从Solidity中调用不能返回数据。一种绕过这个问题的办法是使用一个非常大的静态数组。


pragma solidity ^0.4.16;contract ArrayContract {uint[2**20] m_aLotOfIntegers;// 这里不是两个动态数组的数组,而是一个动态数组里,每个元素是长度为二的数组。bool[2][] m_pairsOfFlags;// newPairs 存在 memory里,因为是函数参数function setAllFlagPairs(bool[2][] newPairs) public {m_pairsOfFlags = newPairs;}function setFlagPair(uint index, bool flagA, bool flagB) public {// 访问不存在的index会抛出异常m_pairsOfFlags[index][0] = flagA;m_pairsOfFlags[index][1] = flagB;}function changeFlagArraySize(uint newSize) public {// 如果新size更小, 移除的元素会被销毁m_pairsOfFlags.length = newSize;}function clear() public {// 销毁delete m_pairsOfFlags;delete m_aLotOfIntegers;// 同销毁一样的效果m_pairsOfFlags.length = 0;}bytes m_byteData;function byteArrays(bytes data) public {// byte arrays ("bytes") are different as they are stored without padding,// but can be treated identical to "uint8[]"m_byteData = data;m_byteData.length += 7;m_byteData[3] = byte(8);delete m_byteData[2];}function addFlag(bool[2] flag) public returns (uint) {return m_pairsOfFlags.push(flag);}function createMemoryArray(uint size) public pure returns (bytes) {// Dynamic memory arrays are created using `new`:uint[2][] memory arrayOfPairs = new uint[2][](size);// Create a dynamic byte array:bytes memory b = new bytes(200);for (uint i = 0; i < b.length; i++)b[i] = byte(i);return b;}
}

补充事例说明

事例代码及讲解,请订阅区块链技术查看。

##参考视频

我们也推出了目前市面上最全的视频教程:深入详解以太坊智能合约语言Solidity
目前我们也在招募体验师,可以点击链接了解。

参考文档

Solidity官方文档-数组

深入浅出区块链 - 系统学习区块链,打造最好的区块链技术博客

智能合约语言 Solidity 教程系列5 - 数组介绍相关推荐

  1. 智能合约语言 Solidity 教程系列9 - 错误处理

    这是Solidity教程系列文章第9篇介绍Solidity 错误处理. Solidity系列完整的文章列表请查看分类-Solidity. 写在前面 Solidity 是以太坊智能合约编程语言,阅读本文 ...

  2. 智能合约语言 Solidity 教程系列8 - Solidity API

    这是Solidity教程系列文章第8篇介绍Solidity API,它们主要表现为内置的特殊的变量及函数,存在于全局命名空间里. <!-- more --> 写在前面 Solidity 是 ...

  3. 智能合约语言 Solidity 教程系列9 - 错误处理 1

    什么是错误处理 错误处理是指在程序发生错误时的处理方式,Solidity处理错误和我们常见的语言不一样,Solidity是通过回退状态的方式来处理错误.发生异常时会撤消当前调用(及其所有子调用)所改变 ...

  4. 区块链技术进阶-深入详解以太坊智能合约语言 solidity(含源码)-熊丽兵-专题视频课程...

    区块链技术进阶-深入详解以太坊智能合约语言 solidity(含源码)-103人已学习 课程介绍         区块链开发技术进阶-深入详解以太坊智能合约语言 solidity视频培训教程:本课程是 ...

  5. 智能合约语言Solidity 类型介绍

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. 智能合约语言Solidity 类型介绍11 Solidity是以太坊智能合约编程语言,阅读本文前,你应该对以太坊.智能合 ...

  6. 智能合约语言Solidity Solidity API

    链客,专为开发者而生,有问必答! 此文章来自区块链技术社区,未经允许拒绝转载. 智能合约语言Solidity Solidity API Solidity 是以太坊智能合约编程语言,阅读本文前,你应该对 ...

  7. 以太坊智能合约语言Solidity - 1 走进Solidity

    1. 走进Solidity 1.1 Remix IDE 界面初识 在本地编写我们可能会遇到各种各样的问题,所以使用在线的Remix编译器来编写合约:https://remix.ethereum.org ...

  8. 智能合约开发solidity编程语言实例

    智能合约开发用solidity编程语言部署在以太坊这个区块链平台,本文提供一个官方实战示例快速入门,用例子深入浅出智能合约开发,体会以太坊构建去中心化可信交易技术魅力.智能合约其实是"执行合 ...

  9. 以太坊智能合约编程简单教程(全)

    有些人说以太坊太难对付,于是我们(译注:指Consensys, 下同)写了这篇文章来帮助大家学习如何利用以太坊编写智能合约和应用.这里所用到的工具,钱包,应用程序以及整个生态系统仍处于开发状态,它们将 ...

  10. 二维数组七行七列C语言,C语言中级教程 再谈数组-7.ppt

    C语言中级教程再谈数组-7ppt课件 * C语言中级培训 七.再谈数组 数组的概念 是一种初级(语言级)形式的数据结构. 数组的特点 无名: 连续: 有序: 等大小: 个数固定(除了在堆上分配): 数 ...

最新文章

  1. 一例IBM服务器Raid磁盘阵列故障
  2. java oracle分页_oracle 分页存储过程和java代码
  3. [转] 前端实现文件的断点续传
  4. python心得体会-终于懂得python基础学习心得
  5. kibana操作elasticsearch:多词条精确匹配(terms)
  6. wxPython布局管理
  7. JSP(Servlet)中从连接池获取连接
  8. C - Insertion Sort Gym - 101955C(2018icpc沈阳/打表找规律)
  9. BZOJ 1051 受欢迎的牛 缩点
  10. java生成iso9660工具_基于数据库的代码自动生成工具,生成JavaBean、生成数据库文档、生成前后端代码等(TableGo v7.0.0版)...
  11. 工程学导论1---3章习题与思考题
  12. linux系统棋牌搭建教程,幼麟棋牌四川麻将搭建教程补充
  13. apk反编译教程+工具
  14. 一文总结图像生成必备经典模型(二)
  15. PLSQL的JOB启动与停止(可视化操作)
  16. EBS杂项出库事务处理
  17. 关于CCNP 642-813交换题库的问题
  18. 服务器作防盗链图片中转,Node.js 上手项目简明教程
  19. 面经 | bigo/联影/58同城20校招计算机视觉算法岗
  20. 雅虎没落,“阿里他爸”拟出售4700亿阿里股份

热门文章

  1. MongoVUE的基本使用
  2. Linux 基础 入门
  3. java sql拼接字符串_java字符串拼接(SQL)
  4. MySQL函数大全,MySQL常用函数汇总
  5. 英文版一元购源码开发解析
  6. 中国大学mooc 慕课 管理信息系统(同济大学) 第八章 电子商务 第九章 信息系统规划 习题 测试答案
  7. 计算机英语听力速记...,2018计算机考研英语听力速记技巧才是王道
  8. DJ-ZBS2漏电继电器
  9. mybatis返回map键值对_Mybatis结果生成键值对
  10. python调用通达信函数大全_通达信dll开发实例,使用python在通达信里面选股