# 数据类型

Solidity 是一种静态类型语言,这意味着每个变量(状态变量和局部变量)都需要在编译时指定变量的类型。

Solidity 提供了几种基本类型,并且基本类型可以用来组合出复杂类型。

“undefined”或“null”值的概念在Solidity中不存在,但是新声明的变量总是有一个 默认值 ,具体的默认值跟类型相关。 要处理任何意外的值,应该使用 错误处理 来恢复整个交易,或者返回一个带有第二个 bool 值的元组表示成功。

# 值类型

以下类型也称为值类型,因为这些类型的变量将始终按值来传递。 也就是说,当这些变量被用作函数参数或者用在赋值语句中时,总会进行值拷贝。

# 布尔类型

bool :可能的取值为字面常量值 truefalse

# 整型

int / uint :分别表示有符号和无符号的不同位数的整型变量。 支持关键字 uint8uint256 (无符号,从 8 位到 256 位)以及 int8int256,以 8 位为步长递增。 uintint 分别是 uint256 和 int256 的别名。

# 地址类型 Address

地址类型有两种形式,他们大致相同:

  • address:保存一个20字节的值(以太坊地址的大小)。
  • address payable :可支付地址,与address相同,不过有成员函数 transfer 和 send 。 这种区别背后的思想是address payable可以接受以太币的地址,而一个普通的address则不能。

类型转换:

允许从address payableaddress的隐式转换,而从addressaddress payable 必须显示的转换, 通过 payable(<address>) 进行转换。

# 合约类型

每一个contract 定义都有他自己的类型。

您可以隐式地将合约转换为从他们继承的合约。 合约可以显式转换为address类型。

只有当合约具有 接收receive函数 或payable回退函数时,才能显式和address payable类型相互转换 转换仍然使用address(x)执行, 如果合约类型没有接收或payable 回退功能,则可以使用payable(address(x))转换为address payable

# 定长字节数组

关键字有:bytes1, bytes2, bytes3, …, bytes32。

# 地址字面常量

比如像 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF 这样的通过了地址校验和测试的十六进制字面常量会作为address类型。 而没有通过校验测试, 长度在 39 到 41 个数字之间的十六进制字面常量,会产生一个错误,您可以在零前面添加(对于整数类型)或在零后面添加(对于bytesNN类型)以消除错误。

# 有理数和整数字面常量

整数字面常量由范围在 0-9 的一串数字组成,表现成十进制。 例如,69 表示数字 69。

# 字符串字面常量及类型

字符串字面常量是指由双引号或单引号引起来的字符串("foo" 或者 'bar')。 它们也可以分为多个连续的部分("foo" "bar" 等效于”foobar”),这在处理长字符串时很有用。 不像在 C 语言中那样带有结束符;”foo” 相当于 3 个字节而不是 4 个。

# Unicode 字面常量

常规字符串文字只能包含ASCII,而Unicode文字(以关键字unicode为前缀)可以包含任何有效的UTF-8序列。 它们还支持与转义序列完全相同的字符作为常规字符串文字。

# 十六进制字面常量

十六进制字面常量以关键字hex打头,后面紧跟着用单引号或双引号引起来的字符串(例如,hex"001122FF")。 字符串的内容必须是一个十六进制的字符串,它们的值将使用二进制表示。

# 枚举类型

枚举是在Solidity中创建用户定义类型的一种方法。 它们是显示所有整型相互转换,但不允许隐式转换。 从整型显式转换枚举,会在运行时检查整数时候在枚举范围内,否则会导致异常( Panic异常 )。 枚举需要至少一个成员,默认值是第一个成员,枚举不能多于 256 个成员。

# 函数类型

函数类型是一种表示函数的类型。可以将一个函数赋值给另一个函数类型的变量,也可以将一个函数作为参数进行传递,还能在函数调用中返回函数类型变量。 函数类型有两类:

  • 内部(internal) 函数类型
  • 外部(external) 函数类型

内部函数只能在当前合约内被调用(更具体来说,在当前代码块内,包括内部库函数和继承的函数中),因为它们不能在当前合约上下文的外部被执行。 调用一个内部函数是通过跳转到它的入口标签来实现的,就像在当前合约的内部调用一个函数。

外部函数由一个地址和一个函数签名组成,可以通过外部函数调用传递或者返回。

# 引用类型

引用类型可以通过多个不同的名称修改它的值,而值类型的变量,每次都有独立的副本。因此,必须比值类型更谨慎地处理引用类型。 目前,引用类型包括结构,数组和映射,如果使用引用类型,则必须明确指明数据存储哪种类型的位置(空间)里:

  • 内存memory 即数据在内存中,因此数据仅在其生命周期内(函数调用期间)有效。不能用于外部调用。
  • 存储storage 状态变量保存的位置,只要合约存在就一直存储.
  • 调用数据calldata 用来保存函数参数的特殊数据位置,是一个只读位置。

# 数组

数组可以在声明时指定长度,也可以动态调整大小(长度)。

一个元素类型为 T,固定长度为 k 的数组可以声明为 T[k],而动态数组声明为 T[]。 举个例子,一个长度为 5,元素类型为 uint 的动态数组的数组(二维数组),应声明为 uint[][5] (注意这里跟其它语言比,数组长度的声明位置是反的)。

# 结构体

支持通过构造结构体的形式定义新的类型,以下是一个结构体使用的示例:

struct Funder {
      address addr;
      uint amount;
  }

# 映射

映射类型在声明时的形式为mapping(_KeyType => _ValueType)。 其中 _KeyType 可以是任何基本类型,即可以是任何的内建类型, bytesstring 或合约类型、枚举类型。 而其他用户定义的类型或复杂的类型如:映射、结构体、即除bytesstring之外的数组类型是不可以作为_KeyType的类型的。

_ValueType可以是包括映射类型在内的任何类型。

映射可以视作 哈希表 ,它们在实际的初始化过程中创建每个可能的key, 并将其映射到字节形式全是零的值:一个类型的 默认值。然而下面是映射与哈希表不同的地方: 在映射中,实际上并不存储 key,而是存储它的keccak256哈希值,从而便于查询实际的值。

正因为如此,映射是没有长度的,也没有 key 的集合或 value 的集合的概念。 ,因此如果没有其他信息键的信息是无法被删除

上次更新: 2022/1/14下午3:56:49