aardio教程二) 進階語法

表(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 發佈!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章