在 Solidity 中,变量声明是智能合约编程的核心部分。Solidity 提供了多种变量类型,允许开发者根据不同需求存储和操作数据。下面详细介绍变量声明的语法和各种变量类型。
1. 变量声明的语法
Solidity 中的变量声明通常包括以下几个部分:
- 类型:变量的数据类型(例如
uint、bool等)。 - 可见性:变量的可见性修饰符(例如
public、private等)。 - 名称:变量的名字。
- 初始化值(可选):赋予变量的初始值。
基本语法:
<type> <visibility> <variableName> = <initialValue>;
2. 变量类型分类
Solidity 中的变量可以分为三大类:
- 值类型(Value Types)
- 引用类型(Reference Types)
- 用户定义类型(User Defined Types)
值类型(Value Types)
值类型的特点是变量直接包含数据值,复制一个值类型变量会生成数据的副本。值类型变量包括以下几种:
-
布尔类型 (
bool)- 存储
true或false。
bool isActive = true; - 存储
-
整数类型 (
int和uint)int:有符号整数,允许负数和正数。uint:无符号整数,只允许正数。- 可以指定位宽(8 到 256 位,步长为 8),例如
int8、uint256。不指定时,默认int和uint为 256 位。
int256 count = -10; // 256位有符号整数 uint8 age = 30; // 8位无符号整数 -
地址类型 (
address)- 存储以太坊账户或合约的地址,分为
address和address payable(可支付的地址,允许接收以太币)。
address owner = 0x1234567890123456789012345678901234567890; address payable recipient = payable(owner); - 存储以太坊账户或合约的地址,分为
-
定长字节数组类型 (
bytes)- 定长字节数组,用于存储字节数据,例如
bytes1到bytes32。
bytes32 hash = 0xabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdefabcdef; - 定长字节数组,用于存储字节数据,例如
-
枚举类型 (
enum)- 用于定义一组命名常量(状态)。
enum State { Created, Locked, Inactive } State public state;
引用类型(Reference Types)
引用类型的特点是变量存储的是指向数据的引用,而非直接存储数据。更改其中一个变量将影响引用同一数据的所有变量。主要有以下几类:
-
动态字节数组 (
bytes)- 动态长度的字节数组,类似于字符串,但可以处理任意字节数据。
bytes data; data.push(0x01); -
字符串类型 (
string)- 字符串是 UTF-8 编码的动态字节数组。
string name = "Solidity"; -
数组类型 (
array)- 一维或多维的集合,可以是静态数组或动态数组。
- 静态数组:长度固定。
- 动态数组:长度可变。
uint[5] staticArray; // 定长数组 uint[] dynamicArray; // 动态数组 -
结构体 (
struct)- 允许用户定义复杂的自定义数据类型,可以包含多个不同类型的变量。
struct Voter { bool voted; uint weight; address delegate; } Voter voter; -
映射 (
mapping)- 键值对存储,类似于哈希表。只能在合约存储中使用,不支持枚举键和值。
mapping(address => uint) public balances;
用户定义类型(User Defined Types)
Solidity 允许开发者定义自己的数据类型。最常见的用户定义类型是 结构体 (struct) 和 枚举 (enum)。
-
结构体 (
struct)- 自定义的复杂类型,可以组合多个数据类型。
struct Product { string name; uint price; } -
枚举 (
enum)- 用于定义一组相关的命名常量。
enum Direction { Up, Down, Left, Right }
3. 变量的存储位置
Solidity 中的变量可以存储在不同的存储位置。存储位置有三种:
storage:存储在区块链上,数据是持久的。memory:临时存储,仅在函数调用期间存在,数据在调用结束后被销毁。calldata:只读的临时存储,主要用于外部函数调用中的参数。
存储位置通常用于函数参数、返回值以及内部临时变量:
function foo(uint[] memory data) public {
uint[] memory tempArray = new uint[](10);
}
4. 变量的可见性修饰符
在 Solidity 中,状态变量可以使用不同的修饰符来控制其可见性和访问性:
public:公开可见,所有人(包括其他合约)都可以访问。private:私有,只有合约内部可以访问,继承的合约无法访问。internal:内部可见,合约内部和继承的合约都可以访问。external:只能被外部合约或交易访问,不能被合约内部的函数调用。
5. 变量的默认值
Solidity 中的变量在声明后会有一个默认值:
bool:默认值是false。int/uint:默认值是0。address:默认值是0x0000000000000000000000000000000000000000。string/bytes:默认值是空字符串。mapping和array:默认是空的。
6. 示例代码
pragma solidity ^0.8.0;
contract Example {
// 状态变量,存储在区块链上
uint public storedValue;
// 结构体类型
struct Person {
string name;
uint age;
}
// 动态数组
Person[] public people;
// 映射
mapping(address => uint) public balances;
// 枚举类型
enum State { Active, Inactive }
State public currentState;
// 函数参数和返回值的类型定义
function setStoredValue(uint _value) public {
storedValue = _value;
}
function getStoredValue() public view returns (uint) {
return storedValue;
}
}