aardio教程二) 進階語法

Python成长路發表於2024-03-17

表(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 釋出!

相關文章