表(table)
aardio中除了基礎數據類型外,其他的複合對象都是table(例如類和名字空間等)。table可以用來存放aardio的任何對象,包括另一個table。
在其他語言中的字典、列表、數組、集合映射等,在aardio中都使用table來實現。
創建字典
import console;
var tab = {
a = 123;
str = "字符串";
[123] = "不符合變量命名規則的鍵應放在下標內。";
["鍵 名"] = "不符合變量命名規則的鍵應放在下標內。";
鍵名 = {
test = "表也可以包含表";
}
}
// 新版也可以使用類json語法定義
var tab = {
"a": 123,
"str": "字符串",
//123: "不符合變量命名規則的鍵應放在下標內。" // 這樣定義鍵不能是數值類型
"鍵名": {"test":"表也可以包含表"}
}
tab.a = 456;
tab["str"] = "aaaa" ;
// 賦值爲null等同於刪除該鍵
tab.鍵名 = null;
// 遍歷
for k,v in tab{
console.dump(k,v);
}
console.pause();
創建數組
var array = {1;2;3;"a"};
// 遍歷
for(i=1;#array;1){
console.dump(i, array[ i ]);
}
數組和字典可以混用
var t = {
1;
2;
a=2;
}
// #只能獲取到數組長度,也就是2
console.log(#t)
// 獲取表長度, 3
console.log(table.count(t))
類
使用class關鍵字定義類。類可以動態創建數據結構相同的table對象
定義類
//定義類
class 類名字{
//構造函數可以省略
ctor( 構造參數列表 ){
//構造函數代碼
}
類屬性 = "屬性值";
類方法 = function(參數){
}
}
和定義一個table的語法基本一樣,只是類可以創建出對象
var 對象 = 類名字();
io.print(對象.類屬性)
對象.類方法();
類的名字空間
定義類時,默認會創建一個同名的名字空間。賦值給名字空間的變量就是類的公用靜態成員
io.open(); //打開控制檯窗口
//定義一個類
class cls{
a = 123;
}
//每一個類擁有獨立的名字空間,名字空間中的變量也就是類的公用靜態成員。
cls.A = "類的靜態成員A";
c = cls(); //創建新對象
io.print( "c.a" , c.a ) //顯示123
io.print( "cls.A" , cls.A ) //顯示"類的靜態成員A";
在庫代碼裏可以經常看到,定義類的時候一般會定義一個同名的名字空間,用於存放一些靜態函數或變量
class base{
a = 123;
b = 456;
c = 789
}
namespace base{
static = 123; //類的靜態成員
}
this對象
也就是Python的self,表示當前對象
owner對象
這個解釋起來比較麻煩,但理解了就很簡單,舉個例子:
class cls{
func = function(){
//類有自已的名字空間,訪問全局對象要加上..前綴
..io.print("owner", owner )
..io.print("this", this )
..io.print("owner == this", owner == this )
}
}
//創建對象
obj = cls();
//打開控制檯
io.open()
//調用對象方法
obj.func(); //默認table與owner是同一個對象
func = obj.func;
func();//這裏owner爲null空值,而this對象沒有改變
當一個table對象調用成員函數時,默認會傳遞一個owner對象給函數。而在類創建的對象成員函數裏,owner對象與this對象是指向同一個對象。
this對象與owner對象的區別在於: this是類內部指向當前創建對象的指針,this指針不會因爲函數的table前綴改變而改變。而owner對象是會根據函數調用時函數名前綴的table對象而相應改變
構造函數
ctor函數就是類的構造函數,等同於__init__
,只是參數沒有self
//定義類
class cls{
//使用ctor關鍵字定義構造函數
ctor( a,b ){
this.a = a;
this.b = b;
}
c = "this.c";
d = "this.d";
}
//調用類的構造函數創建對象
var obj = cls(123,456);
import console;
console.log( obj.a, obj.b )
console.pause();
類的直接繼承
//創建一個基類
class base{
a = 123;
b = 456;
c = 789
}
namespace base{
static = 123; //類的靜態成員
}
class inheritance{
// 構造函數,三個點表示可變參數,類似Python的*args
ctor(...){
// 在類函數裏訪問其他名字空間前面都需要加上.., 內核庫也要,比如..string.format
this = ..base(...); //調用基類構造對象原型。
};
c = "覆蓋基類成員";
d = "子類的新成員";
}
import console;
var obj = inheritance();//從子類創建對象
//輸出對象的所有成員(包括直接繼承的基類成員)
for(k,v in obj){
console.log(k,v);
}
console.pause();
類的間接繼承
class base{
a = 123;
b = 456;
c = 789
}
class inheritance{
c = "覆蓋基類成員";
d = "子類的新成員";
// @表示類的元表,名稱是隨意的
@_prototype;
}
// 在類的名字空間內指定靜態共享成員 _prototype
// 可以在元表中定義相應的元方法,來改變類的一些行爲,比如_get是訪問類屬性時觸發
inheritance._prototype = { _get = ..base() };
import console;
var obj = inheritance();//從子類創建對象
//與類的直接繼承不同
//遍歷只能輸出子類的所有對象,(不會遍歷元表中原型對象的成員)
for(k,v in obj){
console.log(k,v);
}
//通過元方法繼承僅在使用成員操作符時生效
console.log("訪問base類的成員", obj.a );
console.pause();
類的私有成員
用var定義的成員變量,作用域只在類裏面,所以外部無法訪問
類的只讀成員
用下劃線開頭的變量爲類的只讀成員,無法修改它。也可以通過元表來定義只讀成員,元表和元方法的時候再具體說
本文由博客一文多發平臺 OpenWrite 發佈!