Solidity 中允許函數進行重載(overloading),即名字相同但輸入參數類型不同的函數可以同時存在,他們被視為不同的函數。但 Solidity 不允許修飾器(modifier)重載。
舉個例子,我們可以定義兩個都叫saySomething()的函數,一個沒有任何參數,輸出"Nothing";另一個接收一個string參數,輸出這個string。
function saySomething() public pure returns(string memory){
return("Nothing");
}
function saySomething(string memory something) public pure returns(string memory){
return(something);
}
最終重載函數在經過編譯器編譯後,由於不同的參數類型,都變成了不同的函數選擇器(selector)。關於函數選擇器的具體內容可參考WTF Solidity極簡入門: 29. 函數選擇器Selector。
以 Overloading.sol 合約為例,在 Remix 上編譯部署後,分別調用重載函數 saySomething() 和 saySomething(string memory something),可以看到他們返回了不同的結果,被區分為不同的函數。
在呼叫重載函數時,會把輸入的實際參數和函數參數的變數類型做成匹配。 如果出現多個符合的重載函數,則會報錯。下面這個例子有兩個叫f()的函數,一個參數是uint8,另一個為uint256:
function f(uint8 _in) public pure returns (uint8 out) {
out = _in;
}
function f(uint256 _in) public pure returns (uint256 out) {
out = _in;
}
我們呼叫f(50),因為50既可以被轉換為uint8,也可以轉換為uint256,因此會報錯。
庫合約是一種特殊的合約,為了提升Solidity程式碼的複用性和減少gas而存在,庫合約是一系列的函數合集,和普通合約主要有以下幾點不同:
Strings庫合約是將uint256類型轉換為對應的string類型的程式碼庫,範例程式碼如下:
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) public pure returns (string memory) {
// Inspired by OraclizeAPI's implementation - MIT licence
// https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) public pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) public pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
}
他主要包含兩個函數,toString()將uint256轉為string,toHexString()將uint256轉換為16進制,在轉換為string。
用Strings庫合約的toHexString()來示範兩種使用庫合約中函數的辦法。
using Strings for uint256;
function getString1(uint256 _number) public pure returns(string memory){
// 庫合約中的函數會自動加入為uint256型變數的成員
return _number.toHexString();
}
// 直接透過庫合約名調用
function getString2(uint256 _number) public pure returns(string memory){
return Strings.toHexString(_number);
}