多语言展示
当前在线:238今日阅读:84今日分享:32

aauto编程快速入门

快手( AAuto开发环境 ) 下载压缩包仅 6.x MB, 绿色软件解压即用 - 无论个人或企业都可以永久免费使用本软件。快手内置AAuto标准库,以及大量范例全部开源。AAuto用户可以自由使用无需付费,使用AAuto制作的软件产品不需要声明使用AAuto开发,免费使用AAuto无任何附加条件。
工具/原料
1

AAuto开发环境

2

AAuto开发手册

方法/步骤
1

标识符基本规则:标识符由英文字母、中文字符、数字、下划线“_”三种字符组成。数字不允许作为首字符。变量名包含中文时,中文字符前面不能有字母或数字。可以使用美元符号($)作为变量名或变量名的第一个字符。可以使用下划线作为变量名或常量名的首字符,当下划线作为首字符时表示常量,单个下划线表示变量。标识符区分大小。

2

关键字:AAuto支持自定义关键字,例如:def 如果 = ifdef 否则 = elsedef 否则是 = elseifdef 名字空间= namespacedef 循环 = whileio.open();如果 1== 1 { io.print(" 1等于1 ")}否则{ io.print(" 1不等于1 ")}当关键字置于成员符之后,AAuto会将关键字作为普通成员变量名,如下:io.namespace = "io"

3

注释:1、、单行注释单行注释以 //开始,到行尾结束;2、 多行注释多行注释以 /*开始,到 */结束,首尾的*字符可以有一或多个,但*字符的数目必须首尾匹配。

4

操作符:算术运算符:+ - * / % **按位运算符:<< >> >>>等式运算符:= != == === !===逻辑运算符:? : || && == === !===关系运算符:< > >= <= == !==连接运算符:++取长运算符:#包含操作符:$成员操作符:. [ ]   [ [ ] ]

5

表达式:单个操作数可以构成一个表达式。操作数、运算符可以组成表达式,使用运算符对操作数进行运算并返回一个新的值。一个表达式可以作为另一个表达式的操作数。函作返回值可以作为表达式。赋值语句不能作为表达式。

6

语句:语句以分号“;”表示结束,如果能保持语句在语义上的独立完整性,分号“;”通常可以省略。1.1、赋值例如: a = 120;1.2、多重赋值a,b,c = 1,2,3;//将变量声明为当前名字空间下的成员变量value = 100;//以下划线开始的成员常量,只能赋值一次_value = 100; //以下划线开始的全局常量,只能赋值一次 _VALUE = 100; //使用::操作符定义的全局常量,只能赋值一次 ::Value = 100; 1.3、使用var赋值语句定义局部变量局部变量需要用var语句声明。使用局部变量有两个好处 1.避免命名冲突 2.访问局部变量的速度比全局变量更快.1.2、使用赋值语句删除变量将一个变量赋值为null,删除这个变量。例:x = nulla= a + b 可以写成 a += b所有二元操作符都可以按上述规则书写。例如:a -= b;a *= b;A := c 也就是 A = A:c如果A为null空值,则将c赋值给A。定义常量时,为避免重复赋值,通常使用初始化赋值语句。str ?= string.lower(str) 上面的语句等价于: str = str and string.lower(str)如果a不为null空值,则执行后面的赋值语句。其语义如下:if(str != null){    str = string.lower(str)} 这样可以避免str为null空值时,string.lower抛出错误。如果str为空,则等号右侧的语句根本不会执行。a++; 等价于 a += 1;a--; 等价于 a -= 1;C样式语句块使用“{ }” 标明语句块,“{”表示语句块的开始, “}”表式语句块的结束。例如:{     var str = "我是局部变量" ;    io.open();    io.print(str); //输出:我是局部变量};io.print(str);  //输出:null在任何时候,begin ... end 与 { } 都是等价的,可以相互替换使用。if语句可选包含任意多个elseif分支判断语句,可选包含一个else语句。并可以嵌套使用。一个标准的if语句如下:io.open() //打开控制台var a=1if(b==1){    if(a==1) begin        io.print("if")    end}elseif(a==11){    io.print("elseif")}else{    io.print("else")}select case语句select指定一个选择器变量或表达式,case语句列举不同的值或条件值,符合条件的case语句将会执行。case语句默认调用恒等式运算符进行比较。也可以自行指定操作符。例如:io.open() //打开控制台var a = 0;select( a ) {    case 1 { //判断 1===a 是否为真         io.print("a==1")        //其他代码    }    case 1,9,10 { //判断 a 是否其中的一个        io.print("a是1,9,10其中之一")    }    case 10;20 { //判断 ( 10<=a and a <=20 ) 是否为真        io.print("a在10到20的范围")    }    case !=0{ //判断 a是否不等于0,这是自已指定关系运算符的示例        io.print("a不等于0")    }    else{ //所有条件不符时执行else语句块        io.print("a是其他值(0)")    }}select case语句可以嵌套使用。while语句包含条件判断部份、执行代码部份。而循环体可以是一个单独的语句,也可以是用{ } 包含的语句块,也可以是begin end包含的语句块.while 语法如下:while( 条件判断语句 ) {    //需要循环执行的语句}示例代码:io.open() var countLoop = 1 while( countLoop<10 /*这里指定进入并重复执行循环语句的条件*/ ){ countLoop++ io.print("循环次数", countLoop); }; execute("pause") //按任意键继续 io.close();//关闭控制台while var 语句类似while语句,但可以条件判断前添加循环变量初始化、判断条件前执行语句。语法如下:while( var 初始化循环变量列表;判断条件前执行语句;条件判断语句 ) {    //需要循环执行的语句}示例代码:io.open() while(    var next,line = io.lines("~\lib\console\_.aau"); //在循环开始前初始化局部变量    line = next(); //语句或语句块,可省略不写,但不能省略分号    line //循环条件表达式,不可省略 ){      io.print(  line );   };do...while语句包含条件判断部份、执行代码部份。执行代码部份可以是一句代码,或者一个语句块,语句块可以是{ } 包含的语句块,也可以是begin end包含的语句块.do...while语句是首先执行循环体,然后再判断循环条件。循环体至少会执行一次。语法如下:do{    //需要循环执行的语句} while( 条件判断语句 )下面是两层嵌套的while语句示例:do{     io.print(countLoop)    countLoop++}while( countLoop<123 ); //判断条件for循环执行一个固定次数的循环,语法如下:for( 计数器变量= 初始数值; 最大数值; 步进数值) { //步进可以省略,默认值为1。  //需要循环执行的语句} io.open();for( i=1;10;2 ){ //计数器i从1循环到10,每次递增2    io.print(i)}//支持修改计数器变量for( i=1;10;1 )begin    i++;//如果你将i赋值为非数字,在下次循环以前将会被自动恢复为计数器值end;//递减计数器for( i=1;-10;-1 )begin    io.print(i) end;execute("pause") //按任意键继续io.close();//关闭控制台循环中断语句一个好的习惯是:使循环的条件控制集中在循环体的开始或结束,使循环体内部保持良好的内聚性。从而使代码的结构清晰并容易理解、中断语句在一定程度上破坏了这一规则,是以应谨慎的使用中断语句。并且尽可能的使中断语句的使用简洁而清晰、并使他们保持一致性的规律(例如在相同的深度的嵌套层)。1、break语句break语句中断并退出循环并跳转到指定循环的结束点以后开始执行。2、continue语句continue语句跳过循环体剩下的部份,跳转到循环体的开始处并继续执行下一次循环。类似一种不执行循环体剩余部份代码的条件语句。可以在循环体的开始处使用continue语句是一种好的习惯,可以避免将循环体代码包含在一个大的if语句中。使程序拥有清晰的结构。3、带标号的break、continue语句(labeled break、labeled continue)AAuto支持带标号的break、continue语句。标号可以是一个数值,例如 break N; continue N;N指定循环语句的嵌套序号。当前循环用1表示,上层循环为2,再上层为3,依此累加......也可以在循环语句的开始,为循环语句指定一个具名标号,然后使用break lable、continue lable中断指定的循环。循环中断语句一个好的习惯是:使循环的条件控制集中在循环体的开始或结束,使循环体内部保持良好的内聚性。从而使代码的结构清晰并容易理解、中断语句在一定程度上破坏了这一规则,是以应谨慎的使用中断语句。并且尽可能的使中断语句的使用简洁而清晰、并使他们保持一致性的规律(例如在相同的深度的嵌套层)。1、break语句break语句中断并退出循环并跳转到指定循环的结束点以后开始执行。2、continue语句continue语句跳过循环体剩下的部份,跳转到循环体的开始处并继续执行下一次循环。类似一种不执行循环体剩余部份代码的条件语句。可以在循环体的开始处使用continue语句是一种好的习惯,可以避免将循环体代码包含在一个大的if语句中。使程序拥有清晰的结构。3、带标号的break、continue语句(labeled break、labeled continue)AAuto支持带标号的break、continue语句。标号可以是一个数值,例如 break N; continue N;N指定循环语句的嵌套序号。当前循环用1表示,上层循环为2,再上层为3,依此累加......也可以在循环语句的开始,为循环语句指定一个具名标号,然后使用break lable、continue lable中断指定的循环。示例代码:io.open(); //打开控制台 while( true ){ 循环体2: //可以在循环体的开始指定一个标号 io.print("循环体2开始" ); while( true )begin io.print("循环体1开始" ); break 2;//中断上层循环 break 循环体2; //这句的作用与上面的break作用是一样的 io.print("循环体1结束" ); end; io.print("循环体2结束" ); } execute("pause") //按任意键继续io.close();//关闭控制台

7

泛型for与迭代器:迭代指的是一种循环过程,下一步的循环总是以上一步的结果作为基础。踩出第一步,才知道第二步怎么走。屈原有诗“路漫漫其修远兮,吾将上下而求索”描绘的就是一种迭代的思想。迭代不但常用于循环算法,同样也是软件开发过程的核心思想。迭代器(iterator)指的是一个使用迭代算法返回集合成员的函数、可用于泛型for循环语句中.而构造迭代器的函数我们称之为迭代器生成器.next = com.each( com对象 )其中next是一个迭代器,而com.each就是一个迭代器生成器.所以下面的写法:for i,obj in com.each( com对象 ) {    //循环语句 }等价于下面的写法next = com.each( com对象 ) for i,obj in next {    //循环语句 }

8

try...catch容错语句:try语句尝试执行一个语句块,遇到错误则退出try语句块而不是中断AAuto程序。如果使用了catch语句块就可以捕获异常(catch语句块是可选的)。  io.open(); //打开控制台窗口try{    b="aaaaaaaaaaaa" *2    io.print("错误会中断try语句块")}catch(e){ //catch部份可以省略    io.print( "错误信息:",e )    //在这里可以调用debug库    //在栈释放以前调用错误处理     //所以可以调用debug库中的函数收集错误相关的信息}io.print("错误不会中断程序")错误信息不一定要是一个字符串,传递给error的任何信息都会被catch捕获try{    error( {a=2;b=3} ) //error显式抛出一个异常    io.print("错误会中断try语句块")}catch(e){ //catch部份可以省略    io.print( "错误信息:",e.a,e.b) }容错语句是允许多重嵌套的,一个容错语句允许包含另一个容错语句。为了清晰的表示嵌套的层次,需要根据嵌套的层次使用tab制表符缩进。

9

变量:1、成员变量成员变量是属于一个名字空间的成员对象。变量的默认名字空间为global名字空间,并可以使用namespace改变指定代码块的名字空间。可以使用self关键字访问当前名空间。使用..操作符访问global名字空间//没有用var语句显式声明的变量,默认就是当前名字空间的成员变量变量 = "字符串:普通变量";变量 = "变量的值是可以改变的" ..str = 123; //..str等价于 ..global.str2、局部变量var声明一个局部变量,作用域为当前语句块,以及被当前语句块所包含的语句块。var语句声明的局部变量可以指定一个初始值,也可以不指定,建议对所有变量指定初始值。例如:var 局部变量;局部变量 = 123;var a,b,c = 1,2,3io.print( a,b,c,局部变量 )

10

常量:1、字面常量指以数值、字符串等字面值表示数据的对象。象123,"abc"这样的值被称之为字面值,被称为字面值是因为他的值就是代码直接描述的值,并且没有名字可以称呼他,只能用他的值来表示。常量只能赋值一次,重复赋于相同的数字或字符串等常量值将会被忽略,赋于不同的值将会抛出错误。AAuto中的常量以下划线作为起始字符的标识符来表示。2、具名常量用合法的标识符来表示不可修改数据的对象称为常量,与字面值不同的是他具有类似变量名的常量名称。常量名以下划线作为首字符,或使用::操作符将普通的变量转换为常量。具名常量可以理解为赋值后不可修改的变量。2.1 成员常量用字母、数字、中文字符、下划线等组成的标识符来表示,并且必须以下划线作为起始字符。成员常量与成员变量一样默认创建于当前名字空间(self名字空间)、也可以指成员常量的名字空间前缀。成员常量的长度必须大于1并小于256个字节(单个下划线不是常量,在AAuto中通常用作匿名变量占位符)2.2 全局常量用大写字母、数字、下划线等组成的标识符来表示,并且必须以“下划线+大写字母”作为起始字符。全局常量类似于成员常量,区别是必须大写、并且位于globle根名字空间。实际上使用全局对象是不好的习惯,你应当尽可能的避免使用全局对象、将他们放入适当的名字空间。不要介意多打几个字多写几个名字空间前缀,理解了全局对象会不知不觉增加程序的复杂度、并且努力地去避免使用全局对象(这里不是指名字空间、相反应当更多地使用名字空间来组织数据),意谓着你已经成为了一名有经验的程序员。 而且全局常量在AAuto是运行时对象,意谓着会增加发布后的程序体积。把他们改为字面常量并加上注释是一个不错的优化方案,AAuto Quicker提供相应的工具。2.3 转换全局常量可用::前缀将普通的变量强制转换为全局常量。::前缀对变量名的作用是不可逆的,因此在同一个文件中用::声明为全局变量的变量名,即使不再添加::前缀,仍然会被解释为全局常量。::在编译时起作用,并根据编译的顺序拥有向后向下的持久作用域。import语句是在运行时加载外部aau代码、因此import加载的文件中的::操作符不能直接作用于当前代码文件。例如:::Str = "字符串:全局常量" //也可以用::操作符定义一个全局常量(良好的编码习惯是首字母大写)3、使用初始化赋值语句定义常量常量是仅能初始化赋值一次,对于数值常量,重复赋于相同的值会被自动忽略。如果常量的值是非数值对象,即不能保证每次创建的值是相同的,为避免无意中修改常量值导致异常,可使用:=操作符赋值。例如:::Func := function() beginend;上面的代码等效于:::Func = Func or function() beginend;

11

基本数据类型:type.null null 空值,所有变量默认初始值为nulltype.boolean true、false布尔值,表示条件真、假type.number 数值 数值type.string 字符串字符串type.table 数组、哈希表集合(collection)type.function 函数 函数type.pointer 裸指针裸指针(AAuto不负责分配释放),通常来自API函数. 裸指针给你最大的自由,同时也带来最大的风险,如果你不是清楚的了解裸指针指向内存的分配释放规则,尽可策的避免直接使用此类型。type.cdata 托管指针托管指针(AAuto管理分配释放)如果一个托管指针没有元表,则可以直接在API函数中替代pointer类型. 否则,,必须使用_topointer元方法返回裸指针才能在API函数中作为指针使用.type.fiber 纤程 协同程序type.class 类 类nnuull(空值)null即变量没有存储任何数据,将一个变量赋值为null等于删除这个变量booooleeaann(逻辑布尔值)有两个值,true表示真、 false 表示假。通常用在条件表达式中。通俗一点说,true表示是、符合条件,false表示不是、不符合条件。在条件表达式(恒等式除外)中, null、数值0这认为是false,其他有效的数据都被认为是true。 与C++类似,AAuto认为0为false,非零数值为true,在外部api函数中可以保持一致。nnuummbeerr(数值)数值类型可以使用不同的进制来表示,参考:数值与进制 例如使用0前缀表示八进制的数,使用0x前缀表示十六进制数,例:num =0xA1 + 0xFF,而使用2_前缀可以表示2进制数。也可以用科学计算法表示数值 num = 6e+20把一个大于10的数写成a * 10n 的形式,其中a称为尾数、n称为指数,是整数数位只有一位的数,这种计数法叫做科学计数法,也叫10的幂计数法。例如 x= -3.5×105 这里最前面有一个负号,3.5是尾数,两个有效数字,后面以10为基数的指数为5 。我们可以将它表示为-3.5E5。sstrrinng(字符串)字符串就是由多个字符组成的字符串,注意字符与字符串是不同的.字符只是字符串中一个最小的单位。一个英文字符、在内存中占用一个8bit位的字节(8个二进制位),中文字符则占用两个字节。与其他编程语言不同,字符串不仅可用用来存储文本,也可以可以存储二进制数据,允许包含\0。 在C语言中、\0是字符串结束标记。一、、普通字符串普通字符串放在双引号中,字符串可以包含换行,AAuto保证双引号中的字符串换行使用'\n'换行符,不包含'\r'回车符。例如:strPath ="C:\Documents and Settings\admin\Desktop\string.aau" strLine ="第一行第二行"二、、转义字符串转义字符串放在单引号中。支持\转义符,语法与C\C++相同。 AAuto保证单引号中只能以'\r\n'表示回车换行符,所有字面值的回车换行被忽略转义符 说明\\ 表示普通\字符\ddd 用一到三个数字组成十进制数值表示一个字符\xAA 用x后面的两位十六进制表示一个字符\uAAAA 用u后面的四位十六进制表示一个Unicode或双字节字符\a 响铃符(常用于print函数发出警告铃声,例如 io.print('\a')\b 退格\f 换页\r 回车\n 换行\r\n 回车换行\t 制表符(横向跳格)\v 匹配一个垂直制表符。等价于 \x0b\" 双引号\' 单引号\[ 方括号[\] 方括号]转义字符串可以换行、但是AAuto会忽略换行符,必须使用\n表示换行、用\r\n表示回车换行。如果单引号中仅包含一个字符、并且后面附加#号后缀、则表示该字符的字节码数值。示例:io.open()// 字符串中也可以直接用十六进制表示字符,例:io.print('Hel\x6c\x6f world\x21'); //换行被忽略//也可以使用unicode编码表示Unicode字符串,例:string.fromUnicode( '\u4E2D\u6587' )//字符串也可以直用三位十进制数表示字符,格式如\000 例:io.print('Hel\108\111 world\33') //如果单引号中仅包含一个字符,并且在后面加上#号标记,则表示字符的ASCII值io.print( 'A'# ) //显示65注意在转义符串结束后附加#符号表示字节码,附加U或u表示Unicode字符串(以'\0\0'结尾),例如:var wstr = '这是unicode字符串'u注意AAuto的字符串是二进制的,理论上可以支持任意文本编码,当一个文本字符串结尾为'\0\0',AAuto根据需要将其识别为Unicode文本。string.fromto,string.toUnicode等函数的源字符串(也就是第一个参数)可传入以上的unicode字符串并返回正确的结果。 使用此特性,AAuto中的很多功能可以自动支持系统内码以及Unicode编码,例如在web.layout(HTMLayout)中传入文本到界面上即可自由选择是否使用Unicode编码。 在com对象中,文本属性在传入参数或赋值时无论是否unicode都可以自动支持(最终转换为unicode传给com对象), 而从com对象取回文本属性值时,AAuto将自动转换为系统编码,如果在属性名后添加Unicode后缀则返回Unicode编码文本,例如 document.titleUnicode,注意这个后缀不应也不必要用于赋值语句。三、、注释字符串在AAuto的赋值语句中,可以将行注释、段注释作为一个字符串组成赋值语句。在用注释表示字符串时,段注释保证以'\r\n'换行,而行注释保证字符串没有回车符('\r')或换行符('\n')请参考:回车换行符示例:str = //表示原始单行字符串,到行尾结束;str = /* 表示原始多行字符串,首尾的*字符可以有一或多个,但*字符的数目必须首尾匹配*/

12

表:taablee(表)AAuto中使用table数据类型可方便的支持表驱动法编程。table是AAuto中唯一的数据结构类型,用来构建有序或无序的集合(collection)。1、表结构1..1、、哈希表无序集合又称为字典(Dictionaries)、哈希表(hashtable),映射(Map),联合内存(associative memories),联合数组( associative arrays),每个元素都是一个“键值对(key:value pairs )”。“键”可以是字符或其他除null以外的数据类型,甚至可以在table元素中包含table,table允许嵌套。通常把“键”放在索引操作符“[]”中来索引一个元素的值,这时候键又称为“下标”或“索引”。例如 tab["键"] tab[1] ;也可以把一个符合变量命名规则的键放在成员操作符“.”后面,例如 tab.key tab.key2 ; 1..2、、数组table中以从1开始有序连续的数值索引存储的元素构成数组。数组在内存中的存储是有序的。如果table中的部份元素使用了数字键但是并未包含在从1开始有序连续的数值索引中、则构成稀疏数组。在AAuto所指的数组专指有序连续数组。 2、构造表用{}操作符构造新的table对象,并以分号;分隔每一个元素 (不能使用逗号代替分号)。如果成员是一个函数并以}或end结束时,可以省略分隔符。{}操作符在表达式中只能作为赋值表达式的右值、函数参数、或被包含在另一个table构造器中,而不允许与其他操作符结合,不允许向前结合、向后结合,仅允许被括号{}[]()包含。创建一个空的table。days = {}创建一个table数组。days = { "Sunday"; "Monday"; "Tuesday"; "Wednesday";"Thursday"; "Friday"; "Saturday" }//days[1] 的内容是 "Sunday".days[2]的内容就是"Monday"......table元素可以使用各种数据类型的变量,甚至可以是一个表达式或者一个函数,如果我们为table中的值赋于一个键名字,则在table字典中添加一个键值对。point = { x=100 ; y=200 }//point.x 的值是100;point.y 的值是200可以在一个table中同时包括“数组”、“字典”。tab = {x=100;y=200;"Sunday"; "Monday"}//tab.x 的值是100;tab.y 的值是200table的键名并不要求符合变量命名规则,键可以是任何除null以外的值或字符串。但是在{}构造器中的键名必须符合变量命名规则。 在任何时候,table中不符合变量命名规则的键必须通过[]操作符访问,以下是正确的写法:tab = { [1]=300;[2]=400;["+"]=200;[1+1]=200 }; //因为变量名不能以数字开始,更不能包含运算符。以上的写法等价于tab ={};tab[1]=300;tab[2]=400;tab["+"]=200;tab[1+1]=200;我们可以把多个变量用一对花括号包含起来以转换为table数组,也可以通过table.unpack函数将table数组转换为多个变量。tab = {"a";"abc";"abcd"} ; //创建一个table;a,b,c = table.unpack(tab);tab ={ table.unpack(tab) }; //将所有返回值转换为table变量tlinks3、、在函数参数中构造表当在函数内部有且只有一个使用{}构造器构建的table参数时,并且不包含数组元素,则{}可以省略。例如: func( { k = 123 ; k2=456 } )可以省略{}写成如下格式: func( k = 123 ; k2=456 )4、、访问taablee成员在访问table中的元素时,用元素的键作为下标查询元素的值,例如:tab = {}; //用一对花括号创建一个空的tabletab["x"] = 200; //下标为字符串"x",键名为字符串"x",值为数值200。tab[1] = "hellor world"; //下标为数字1,键索引为1,值为字符串 "hellor world"如果“键”是一个数字索引称为“键索引”,如果键是一个字符串称为“键名” ,对于符合变量命名规范的键名,可以用"."成员符访问。例如:tab["x"] = 200; 也可以写为 tab.x = 200;当我们将tab元素赋值为null会删除这个元素。例如: tab.x = null; //删除tab.x4、、遍历taablee遍历table列表中的全部元素io.open(); //打开控制台窗口,用来支持print函数tab = { a="字符串"; b=123; c="字符串2"; d=23; e=56; 78; 99; 123; 0 }for k,v in tab {  //k为键,v是匹配的值,在这里键值对无序的随机出现。 io.print(k,v); //显示: 键,值 };遍历table列表中的数组元素io.open(); //打开控制台窗口,用来支持print函数tab = { a="字符串"; b=123; c="字符串2"; d=23; e=56; 78; 99; 123; 0 }for i=1; #tab;1 { io.print( i ,tab[i] );}

13

fuunncctioonn(函数)函数是一个子程序,可以接收零个或多个参数、返回一个或多个值。使用function关键字定义函数,使用()操作符调用函数。请参考:定义函数ccdaataa(内核对象)对象是由AAuto管理的指针对象,由AAuto自动管理cdata指向的内存,并在不需要的时候自动释放。一般cdate对象由AAuto内核提供。可以通过元表指定成员方法、重载操作符,使之有类似table的行为。如果指定了_topointer元言法则可以自动转换为裸指针供API函数使用。io.open(); //打开控制台窗口io.print( type( io.stdin ) , type.cdata );//显示 cdata ,cdata使用raw.malloc函数可以动态创建cdata类型的内存指针、可以使用索引操作符存取数据、可以在API函数中自动转换为裸指针,不应当为raw.malloc创建的cdata对象指定元表,这会导致索引操作符失效。 buf = raw.malloc(123) buf[1] = 65io.open()io.print(buf[1])//对于溢出下标返回数值0io.print(buf[-1]) cclaassss(类)使用class关键字定义类。类可以动态创建数据结构相同的table对象。 请参考:classfiber(纤程)fiber.create()创建并返回的纤程对象。 纤程类似线程,但不是线程. 纤程有独立的运行堆栈,并且也可以暂停或继续运行,但是纤程并不会创建新的线程,也不能同时运行多个纤程.请参考:内置库->纤程库转换数据类型数值、字符串会自动转换,但是我们也可以用AAuto提供的函数强制转换。AAuto提供三个强制转换动态类型的函数tostring(v) 转换参数v为字符串,可使用_tostring元方法自定义转换函数。tonumber(v) 转换参数v为数值,可使用_tonumber元方法自定义转换函数。topointer(v) 转换参数v为指针,可使用_topointer元方法自定义转换函数。io.open(); //打开控制台窗口,用来支持io.print函数n = tonumber( "2" );//tonumber函数强制转换一个变量为数字,如果失败返回null空值str = tostring( 2 );//强制转换一个变量为字符串,如果失败返回null空值ptr = topointer( 123 ); //强制转换为指针,如果失败返回null空值io.print( type(n),type(str),type(ptr) );使用typee函数可以读取数据类型。。1、、函数原型::dataType[,structType][,metaType] = type( any )2、、函数说明::type函数返回对象的基本数据类型dataType。如果对象是一个struct结构体,则返回结构体类型structType。如果对象在元表中指定了_type字段的值,则返回元类型metaType。AAuto用字符串描述类型,所以返回的类型都是字符串, 如果没有任何参数,type函数无返回值. 3、、调用示例::io.open(); //打开控制台窗口io.print( type(null) , type.null );//显示null , nullio.print( type("Hello world") , type.string );//显示string , stringio.print( type(1000) , type.number );//显示 number ,numberio.print( type(io.print) , type.function );//function ,functionio.print( type( class{} ) , type.class );//显示 class ,classio.print( type(true) , type.boolean );//boolean , booleanio.print( type( io.stdin ) , type.cdata );//显示 cdata ,cdataio.print( type( {x=0;y=0} ) , type.table );//显示 table ,tableio.print( type( topointer( 1 ) ) , type.pointer );//显示 pointer , pointer使用typee..eeq比较数据类型  1、、函数原型::eq = type.eq( obj,obj2 )2、、函数说明::比较参数一、参数二的类型、元类型、sturct类型,如果完全相等返回true,否则返回false3、调用示例:import time.oleio.open(); //打开控制台窗口var oletm = time.ole();var tm = time(); //type.eq严格比较所有类型(基础类型、元类型、struct类型)if( type.eq( oletm,tm ) ){ io.print("oletm,tm类型相同")}else{ io.print("oletm,tm类型不相同")}//time.istime不比较元类型,因此兼容oletimeio.print( "是datetime对象吗?",time.istime(oletm) )execute("pause") //按任意键继续io.close();//关闭控制台

注意事项
1

这是一个aauto语言语法规则

2

你可以参考,写自己的编程语言

推荐信息