访问修饰符
-
private
:可修饰函数和状态变量;表示仅能在合约内部访问 -
internal
:可修饰函数和状态变量;表示仅能在合约内部或者继承合约内部访问 -
public
:可修饰函数和状态变量;表示任何地方都能访问 -
external
:仅可用于修饰函数;表示仅能在合约外部访问
solidity
contract Demo {
uint private privateVar = 1;
uint internalVar = 2; // default internal
uint public publicVar = 3;
function privateFunc() private view returns (uint) {
return privateVar;
}
function internalFunc() internal view returns (uint) {
return internalVar;
}
function publicFunc() public view returns (uint) {
return publicVar;
}
function externalFunc() external pure returns (uint) {
return 4;
}
function testFuncInDemo() public view {
privateVar + internalVar + publicVar;
privateFunc();
internalFunc();
publicFunc();
// externalFunc();
}
}
contract Child is Demo {
function testFuncInChild() public view {
publicVar + internalVar + publicVar;
// privateFunc();
internalFunc();
publicFunc();
// externalFunc();
}
}
contract External {
Demo demo = new Demo();
function testFunc() public view {
demo.publicVar;
// demo.privateFunc();
// demo.internalFunc();
demo.publicFunc();
demo.externalFunc();
}
}
在 Solidity 中,public 修饰的状态变量会自动生成 getter 函数,一般情况下 可以直接访问变量,但也有需要调用 getter 的情况:
solidity
contract Demo {
uint public publicVar = 1;
}
contract DemoExternal {
Demo demo = new Demo();
function testFunc() public view returns (uint) {
demo.publicVar; // 直接访问
return demo.publicVar(); // 通过 getter 访问
}
}
函数修饰符
pure
函数既不能读取也不能修改合约的状态变量。view
函数可以读取合约的状态变量,但不能修改它们。
solidity
contract Demo {
uint public x = 10;
function pureFunc(uint a, uint b) public pure returns (uint) {
return a * b;
}
function viewFunc() public view returns (uint) {
return x;
}
}
会修改状态变量的函数不需要函数修饰符:
solidity
contract Demo {
uint public count;
function increment() external {
count++;
}
}
变量修饰符
- 可用
constant
关键字声明在编译时确定值的常量 - 可用
immutable
关键字声明在部署时确定值的变量。
solidity
contract Demo {
uint public constant NUM = 100;
address public immutable OWNER;
constructor() {
OWNER = msg.sender;
}
}
数据修饰符
在函数中,可用 storage、memory、calldata 修饰引用类型数据。
storage
:可用于本地变量;会告诉编辑器,此处操作的是数据引用memory
:可用于本地变量、参数、返回值;会告诉编辑器,此处操作的是数据副本calldata
:可用于参数;会告诉编辑器,数据只读
solidity
contract Demo {
struct Person {
string name;
uint256 age;
}
Person[] public persons;
// calldata: 可用于参数; 会告诉编辑器, 数据只读
function addPerson(string calldata _name, uint256 _age) public {
persons.push(Person(_name, _age));
}
function getPerson(
uint256 _index
) public view returns (string memory, uint256) {
// memory: 可用于本地变量、参数、返回值; 会告诉编辑器, 此处操作的是数据副本
return (persons[_index].name, persons[_index].age);
}
function updatePerson(
uint256 _index,
string calldata _name,
uint256 _age
) public {
// storage: 可用于本地变量; 会告诉编辑器, 此处操作的是数据引用
Person storage person = persons[_index];
person.name = _name;
person.age = _age;
}
}