# 表达式和结构
输入参数的写法:
输入参数的声明方式与变量相同。但是有一个例外,未使用的参数可以省略参数名。 例如,如果我们希望合约接受有两个整数形参的函数的外部调用,我们会像下面这样写
pragma solidity ^0.4.16;
contract Simple {
function taker(uint _a, uint _b) public pure {
// 用 _a 和 _b 实现相关功能.
}
}输出参数的写法:
输出参数的声明方式在关键词 returns 之后,与输入参数的声明方式相同。 例如,如果我们需要返回两个结果:两个给定整数的和与积,我们应该写作
pragma solidity ^0.4.16;
contract Simple {
function arithmetics(uint _a, uint _b)
public
pure
returns (uint o_sum, uint o_product)
{
o_sum = _a + _b;
o_product = _a * _b;
}
}输出参数名可以被省略。输出值也可以使用 return 语句指定。 return 语句也可以返回多值,参阅:ref:multi-return。 返回的输出参数被初始化为 0;如果它们没有被显式赋值,它们就会一直为 0。
输入参数和输出参数可以在函数体中用作表达式。因此,它们也可用在等号左边被赋值。
内部函数的调用:
pragma solidity ^0.4.16;
contract C {
function g(uint a) public pure returns (uint ret) { return f(); }
function f() internal pure returns (uint ret) { return g(7) + f(); }
}外部函数的调用方法:
pragma solidity ^0.4.0;
contract InfoFeed {
function info() public payable returns (uint ret) { return 42; }
}
contract Consumer {
InfoFeed feed;
function setFeed(address addr) public { feed = InfoFeed(addr); }
function callFeed() public { feed.info.value(10).gas(800)(); }
}payable 修饰符要用于修饰 info,否则,.value() 选项将不可用。
注意,表达式 InfoFeed(addr) 进行了一个的显式类型转换,说明”我们知道给定地址的合约类型是 InfoFeed “并且这不会执行构造函数。 显式类型转换需要谨慎处理。绝对不要在一个你不清楚类型的合约上执行函数调用。
我们也可以直接使用 function setFeed(InfoFeed _feed) { feed = _feed; } 。 注意一个事实,feed.info.value(10).gas(800) 只(局部地)设置了与函数调用一起发送的 Wei 值和 gas 的数量,只有最后的圆括号执行了真正的调用。
如果被调函数所在合约不存在(也就是账户中不包含代码)或者被调用合约本身抛出异常或者 gas 用完等,函数调用会抛出异常。
函数名称调用:
pragma solidity ^0.4.0;
contract C {
function f(uint key, uint value) public {
// ...
}
function g() public {
// 具名参数
f({value: 2, key: 3});
}
}匿名函数调用:
pragma solidity ^0.4.16;
contract C {
// 省略参数名称
function func(uint k, uint) public pure returns(uint) {
return k;
}
}如果它们被包含在 {} 中,函数调用参数也可以按照任意顺序由名称给出, 如以下示例中所示。参数列表必须按名称与函数声明中的参数列表相符,但可以按任意顺序排列。必须和设置的函数的值数量类型保持一致。




