在上一篇文章 《以太坊Solidity智能合約開發(一) – 合約結構》中,我們學習掌握了簡單的合約的基本結構,在這篇文章中,我們將開始學習合約的值類型和引用類型,讓我們繼續往下學習。
一. 值類型
佈爾型
bool :可能的取值為字面常數值 true 和 false 。
運算符:
! 《邏輯非》&& 《邏輯與, “and” 》|| 《邏輯或, “or” 》== 《等於》!= 《不等於》
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Boolean {
bool isTrue; // bool類型
// …
}
整數類型
int / uint :分別表示有符號和無符號的不同位數的整型變量。
支持關鍵字 uint8 到 uint256 《無符號,從 8 位到 256 位》以及 int8 到 int256,以 8 位為步長遞增。
uint 和 int 分別是 uint256 和 int256 的別名。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Integer {
uint8 age;
uint256 weight;
// …
}
地址類型
address:地址類型存儲一個 20 字節的值《以太坊地址的大小》。
地址類型也有成員變量,並作為所有合約的基礎。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Account {
address addr; // address類型
// …
}
定長字節數組
關鍵字有:bytes1, bytes2, bytes3, …, bytes32。
byte 是 bytes1 的別名。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Bytes {
bytes1 number1;
bytes32 number2;
// …
}
地址字面量
地址值的長度一定是符合以太坊的正確的公鑰地址。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Accounts {
address account = 0xdCad3a6d3569DF655070DEd06cb7A1b2Ccd1D3AF; // 地址字面量
// …
}
數值字面量
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Accounts {
uint128 a = 1; // 數值字面量
// …
}
字符字面量
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract String {
string account = “str”; // 字符字面量
// …
}
枚舉類型
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract test {
enum ActionChoices { GoLeft,GoRight,GoStraight,SitStill }
ActionChoices choice;
ActionChoices constant defaultChoice = ActionChoices.GoStraight;
function setGoStraight() public {
choice = ActionChoices.GoStraight;
}
function getChoice() public view returns (ActionChoices) {
return choice;
}
function getDefaultChoice() public pure returns (uint) {
return uint(defaultChoice);
}
}
函數類型
函數類型是一種表示函數的類型。
可以將一個函數賦值給另一個函數類型的變量,也可以將一個函數作為參數進行傳遞,還能在函數調用中返回函數類型變量。
函數類型有internal內部函數,external外部函數,public公共函數,private私有函數,view函數和pure純函數。
其中,internal內部函數隻能在本合約和繼承本合約的內部被調用,private私有函數隻能在本合約被調用。
external外部函數隻能被外部的合約調用,public公共函數可以在任何情況下都能被調用。
view函數說明這個函數隻有隻讀功能,pure純函數說明這個函數也是隻有隻讀功能,兩者區別在於view可以進行運算,但是會發出警告,且結果不回因為運算而發生改變。
pure是嚴令禁止寫入的功能的。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract test {
uint age;
function func_external() external { // 外部函數
// …
}
function func_internal() internal { // 內部函數
// …
}
function func_public() public { // 公共函數
// …
}
function func_private() private { // 私有函數
// …
}
function getAgeByView() public view returns(uint){
age += 1; // 編譯不通過
return age; // return 30,但是!狀態變量age的值不會改變,仍然為29!
}
function getAgeByPure() public pure returns(uint){
return age; //編譯報錯!pure比constant和view都要嚴格,pure完全禁止讀寫狀態變量!
return 1;
}
}
內存關鍵詞
memory 和 storage
由於Solidity語言受到自身堆棧深度的限制,所以我們必須手動為數據分配存儲位置。
由於拷貝這些類型變量的開銷相當大,我們不得不考慮它的存儲位置,是將它們保存在 內存memory 《並不是永久存儲》中, 還是 存儲storage 《保存狀態變量的地方》中。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Person {
struct Student {
string name;
string status;
}
Student[] students;
function test(uint _index) public {
// Solidity 將會給出警告,告訴你應該明確在這裡定義 `storage` 或者 `memory`。
// 這裡定義為 `storage`:
Student storage stu1 = students[_index];
stu1.status = “Active!”;
// 如果你隻想要一個副本,可以使用`memory`:
Student memory stu2 = students[_index + 1];
stu2.status = “Negative!”;
}
}
二. 引用類型
字符串類型
string類型是一個字符序列。
Solidity 支持使用單引號’ ‘和雙引號” “的字符串文字。
// SPDX-License-Identifier: MIT
pragma solidity ^ 0.8.13;
contract String_Example{
string name = “John Doe”;
}
數組類型
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract test {
uint[] public arrays; // 數組
function func_array() external { // 外部函數
arrays.push(1); // 存放1
}
}
映射類型
映射類型在聲明時的形式為 mapping(_KeyType => _ValueType)。
其中 _KeyType 可以是除了映射、變長數組、合約、枚舉以及結構體以外的幾乎所有類型。
_ValueType 可以是包括映射類型在內的任何類型。
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Person {
struct Students {
string name;
uint age;
}
uint[] arrays;
mapping(uint => address) map1; // value為address類型
mapping(string => Students) map2; // value為結構體類型
mapping(uint => mapping(uint=>string)) map3; // value為mapping類型
}
結構體類型
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract Person {
struct Students {
string name;
uint age;
}
}
以上這些都是常用一些數據類型,掌握了其寫法後,我們後面就開始寫大量的一些示例來具體學習,遇到不懂的,我們再來深入學習它,理解它。
當然,提倡並鼓勵大家多看官方的文檔教程。