目录
函数
在Solidity中,函数是用来执行特定任务的代码块。它们可以被定义在合约中,并被其他代码或外部调用。
1.solidity中函数的形式:
function <function name> (<parameter types>){public|private|internal|external}[pure|view|payable] [returns (<return types>)]
-
function
:声明函数时的固定用法,想写函数,就要以function关键字开头。 -
<function name>
:函数名。 -
(<parameter types>)
:圆括号里写函数的参数,也就是要输入到函数的变量类型和名字。 -
{public|private|internal|external}
:函数可见性说明符,一共4种。没标明函数类型的,默认internal
。
public
:任何地址都可以调用该函数。private
:仅合约内部可以调用,其他合约和地址无法访问。internal
:仅合约内部和继承合约可以调用,其他地址无法访问。external
:仅可以从合约外部调用,合约内部无法调用。
-
[pure|view|payable]
:决定函数权限/功能的关键字。payable
(可支付的)很好理解,带着它的函数,运行的时候可以给合约转入ETH
。pure
和view
的介绍见下一节。 -
[returns ()]
:函数返回的变量类型和名称。
2.函数可见性
Solidity中函数的可见性修饰符:public
、private
、internal
和external
,用于控制谁可以调用函数。
-
public
: 使用public
修饰符标记的函数可以被合约内部的其他函数、外部账户以及其他合约进行调用。这是最常见的可见性修饰符,默认情况下,如果不指定可见性修饰符,函数会被认为是public
的。示例:
function doSomething() public { // 函数逻辑 }
-
private
: 使用private
修饰符标记的函数只能在当前合约内部被调用,无法被外部账户或其他合约直接访问。示例:
function internalFunction() private { // 内部函数逻辑 } function doSomething() public { // 调用私有函数 internalFunction(); }
-
internal
: 使用internal
修饰符标记的函数可以在当前合约内部被调用,以及继承合约中被调用。外部账户或其他合约不能直接访问和调用这些函数。示例:
contract Base { function internalFunction() internal { // 内部函数逻辑 } } contract Derived is Base { function doSomething() public { // 调用内部函数 internalFunction(); } }
-
external
: 使用external
修饰符标记的函数只能从合约外部进行调用,合约内部无法直接调用这些函数。示例:
contract MyContract { function externalFunction() external { // 外部函数逻辑 } } function caller() { MyContract contractInstance = new MyContract(); // 调用外部函数 contractInstance.externalFunction(); }
external
修饰符只能用于函数声明,而不能用于函数定义。这意味着在函数定义的代码块中,无法使用external
修饰符。
3.函数可选性
pure
、view
和payable
是Solidity中的函数可选性关键字,用于进一步定义函数的行为,由于其他编程语言没有类似的关键字,所以我们单独了解一下:
-
pure
关键字:使用pure
关键字修饰的函数表示它不会修改合约的状态,也不会读取合约的状态或全局变量,仅通过输入参数计算并返回结果。这样的函数可以在任何可见性修饰符内使用。示例:
function add(uint a, uint b) public pure returns (uint) { return a + b; }
在这个示例中,
add
函数被定义为pure
,并且在合约的任何部分都可以调用。它不会修改合约状态,也不会读取状态变量,只是简单地计算输入参数的和并返回结果。 -
view
关键字:使用view
关键字修饰的函数表示它不会修改合约的状态,但会读取合约的状态或全局变量。这样的函数可以在任何可见性修饰符内使用。示例:
function getBalance(address account) public view returns (uint) { return balances[account]; }
在这个示例中,
getBalance
函数被定义为view
,它可以在合约的任何部分被调用。它不会修改合约状态,只是简单地读取balances
的映射状态变量的值并返回结果。 -
payable
关键字:使用payable
关键字修饰的函数表示它可以接收以太币(ether)作为调用的一部分,并且可能会修改合约的状态。示例:
function deposit() public payable { balances[msg.sender] += msg.value; }
在这个示例中,
deposit
函数被定义为payable
,它可以在合约的任何部分被调用,允许发送以太币到合约并将其存储在发送者的账户中。
view
和pure
函数在内部调用时,也只能调用其他view
或pure
函数,而不能调用任何可能修改合约状态的函数。
4.返回值 return和returns
在Solidity中,函数可以通过使用 return
或 returns
关键字来返回值给函数的调用者,他们的区别在于:
returns
加在函数名后面,用于声明返回的变量类型及变量名;return
用于函数主体中,返回指定的变量。
-
使用
return
关键字:如果函数只有一个返回值,可以使用return
关键字来返回结果。示例:
function add(uint a, uint b) public pure returns (uint) { return a + b; }
在这个示例中,
add
函数接受两个参数a
和b
,并返回它们的和。在函数体中使用return
关键字将结果返回给函数的调用者。 -
使用
returns
关键字:如果函数有多个返回值,应该使用returns
关键字来明确声明每个返回值的类型和名称。示例:
function divide(uint a, uint b) public pure returns (uint quotient, uint remainder) { quotient = a / b; remainder = a % b; }
在这个示例中,
divide
函数接受两个参数a
和b
,并将它们进行除法运算,返回商quotient
和余数remainder
。通过returns
关键字明确指定了两个返回值的类型和名称,但是,returns
关键字只能在函数的可见性修饰符之后声明,因此需要将它们放在函数签名的最后。