aardio学习笔记
这个函数的主要作用是:主要功能用为显示变量或字符的类型
2.所有变量的默认初始值是null,也就是定义一个变量不给他任何值,它就是null
var a;
console.log(type(a)) //返回变量的类型字符串,table,string,number 这三种会直接显示它的值,其它会显示它的类型字符串
这里我们看到type 第一种用法,作用是显示变量的类型字符串
3. console的log和dump有什么区别?
答:一般不是表,我们都用log,表用dump
4.null即变量没有存储任何数据,将一个变量赋值为null等于删除这个变量
null 还有一个重要功能就是,将一个变量赋值为null 相当于删除这个变量
5.number数值类型:数值默认存储为 64位浮点数(即静态类型中的 double 类型)
6.string类型:字符串用这三种符号括起的都属于字符串,双引号,单引号,后引号
在aardio中,单引号括起的字符串,是可以使用转义符的,
所以平时不建议用单引号来挺括起字符串
应该用双引号或后引号
为什么有后引号?是因为有时会出现字符串中要输出双引号和单引号的情况
在多行的时候,用单引号的字符串是不会换行
字符串拼接用 ++ ,++ 号会将两边的变量都转换为字符串进行连接,是强制转换,而一个 + 号操作符,如果一边是数字,那么就会尝试转换另一边的字符串为数字型,如果两边都是字符串,那么用一个+号也是可以的, 两边都是数字,用一个+ 号,那么就会把两边都转换成数字,然后再相加,按照数值进行计算了,所以如果不知道 两边都是什么类型,那么还想字符串拼接,那么就直接用++ 两个加号,如果进行数值运算就最好转换数值类型再相加
7.三个转换类型的函数
tostring:
tonumber:tonumber的返回值有两个,一个是将参数转换后的数值,一个是参数的字符数,所以我们可以用两个变量接收它的返回值
那又会想这么麻烦,我只想要第一个参数,其它不要,用一行能不能搞定,在函数外层再加一层括号,就能只返回第一个值,
用到我们另一个全局函数 rget 用于选择返回值,参数2 是 我们要返回值的函数,参数1 是定义一个截取的起始位置,注意这里的参数1是定义截取位置,如果是1,代表着后面的第2,3,4等等参数也会返回
topointer: 转换为指针
string.concat:字符串连接函数,它在连接时,参数即使是null也不会报错
8.如果一个null的变量进行++ 强制类型转换也会出现错误
9.===是表示恒等式,它不但会判断值,还会判断类型是否相等,
a 是字符串类型,b 是数字类型,但是用=号或==号时,判断出来是相等的,也就是跟上面说的一样会自动转换类型为判断,这时,我们想类型也判断,不但判断值,就需要用恒等式===
10. type.eq函数:
比较的是两个变量是不是同一种类型
11.
这里有个坑,就是其它语言会将空字符串 "" 转换为布尔值是false ,但是在aardio中空字符串也是true
12.
# 符是会取字符串的字节数; 举例:
13.
table 我们叫表,这种数据类型,实际是一个数据的集合,就是将一些数据集合在一起进行统一管理,表在其它语言中,被称为字典(dictionaries)、列表(list)、映射(map)、关联数组(associative arrays)、对象(object)......等,分为有序和无序两种,
有序集合:实际就是数组
无序集合:是哈希表,利用哈希算法,特点是即使数据量很大存取速度也快
创建空的表:var tab = {};var tab = {1;2;3}; 注意aardio序号是从1开始,而不是0
14.
还记得之前说过的类型null吗,当一个变量赋值为null,相当于删除这个变量
注意,这里有一个点:用null删除后,索引是不变的,如果想让索引重新排列就需要使用table.remove方法了
import console;
var tab = {1;2;3}
//使用table库的remove方法删除值可以令序号重新排列
table.remove(tab,2) //删除第二个元素
console.dump(tab)
console.pause(true);
所以如果要删除数组的某个元素,最好用table.remove
15.表的数据类型可以是任何数据类型,包含它本身
16 .
string.save将字符保存文件
17.表的遍历:
可以用# 符来取数组的个数,
#tab1 的值 6 就是数组的元素总数
18.无序数组的遍历,也就是表的遍历 ,#号无法获得无序表的个数,但可以使用table.count方法
19.
哈希表想按顺序来打印,有两个方法,一个是table.eachName 按键来排序, 一个是table.eachValue 按值来排序
第二个参数也可以是一个自定义排序函数
21.
22.普通aardio文件中的作用域:
它的作用域是: 从它定义开始那一行起,到文件结束,文件就是一个大的语句块
import console; console.log("能找到吗",num) var num = 1 // 我的作用域范围是从这里开始 console.log(num) console.pause(true);
23. aardio创建工程时文件的对应关系
24 .右键 用户库-》新建库-》
namespace 是创建名字空间关键字, 后面跟的是名字空间名,名字空间名跟文件名一致,aardio才会找到这个文件,不然后面用 import 导入会出错
25. 成员变量很简单,就是不用var定义
26.global 这个可以用 .. 来代替,这样可以更方便使用
import console 相当于在 c:\ 复制一个 console目录 , 它的路径是 c:\console
namespace newtest 相当于 在c:\创建一个目录 newtest , 它的路径是 c:\newtest
在 c:\newtest 直接打开 console\log文件 可能吗,这当然就会出错了
27.
在没有定义类或名字空间外,定义的变量都在global,
class , namespace , class 是类,它也是一个名字空间,在它们的外面定义的变量,没有用var的
,就是在global,如果是var就是之前所讲的作用域
28 .
总结下,var定义的局部变量有保护变量的作用,其它文件不能调用;成员变量可以加前缀来访问
29.
可以看出常量
1. 值不能被改变
2. 只能初始化时赋值一次
字面常量 其实就是我们平时用到的数据;
成员常量:定义的时候是 下划线 + 小写字母开头
全局常量:有两种表示方式 , 一种是 下划线 + 大写字母
全局变量,是会占程序体积的,没有必要就不要定义全局常量,
因为是全局的,一旦被创建,直到程序结束都占用内存,不像变量会释放,全局常量,也是无视名字空间的,作用域是整个程序
30.
先讲这个 _STUDIO_INVOKED ,这个是用来判断,我们是不是在ide环境,如果不是就返回null,是就会返回一个值process或thread等,这个值不重要,重要是能判断是不是在ide环境
27.
回到全局变常量,还有一种就是用 :: 为前缀的全局常量,
如果说下划线程+ 大写字母来定义一些api函数用到的参数值,或者预定义的值,那么这个::前缀一般用来定义api函数转换为aardio的函数
28.
string.split 是分割字符串,第二个参数是分隔的字符,如果是空字符串时就会按每个字符来分割,返回一个字符串的数组
29. aardio的转义字符,只能放在单引号中
30. a:=5 //这个表示,如果a之前有定义过真值,那么后面就不会再赋值,这个可以避免重复赋值,特别用于常量
31. while循环:
32.输入对话框
33. 变量的定义:一般习惯用 变量 = function 形式
34.匿名函数的调用:
35.
这种加大括号就能变成表的方法,非常之有用
36. string.load("/a.txt") //使用该方法读取文本内容
37. 注意这个例子:因为a,b,c,d是标识符,它不是属于数据类型,
就像我们平时写个a只是一个变量名,没有赋值就是null,加上双引号,就是字符串,就会显示了,同时也看到eval函数外面包了一个大括号
38.lambda表达式用于定义匿名函数,它实际就是一个简写的匿名函数,但有一点不同的是它没有函数体
正常函数:
lambda写法:
还有一点注意的是,它不像普通函数可以返回多个值,lambda只能返回一个值,匿名函数赋值给一个变量的时候,它就有了名字,就可以返回多个值
lambda还可以使用希腊字母代替
求最大值的lambda的写法:
还可以这样写:
40.闭包
总结:函数套子函数并返回子函数,那么函数内定义的变量就会被保留
这个例子说明,当函数返回值为null时(一般函数不写return就是返回null) ,它就会停止继续调用函数
当 闭包 遇上 for in ,它们就产生 "迭代"
这个闭包的函数就叫做迭代器,迭代器简单的讲就是在for in语句用于循环取值的函数
41. 类中用var定义的是私有属性,外面是访问不到的
42 .三个关键字:
self:表示当前名字空间
owner:调用对象的前缀对象
this:动态创建的对象
this对象与owner对象的区别在于。
this是类内部指向当前创建对象的指针,this指针不会因为函数的table前缀改变而改变。而owner对象是会根据函数调用时函数名前缀的table对象而相应改变。
实际self在类里面是不能调用类的属性或方法,也就是在类里面用self没啥用
43.
名字空间是可以直接调用成员,而类必须要实例化后才可以用,是不一样的
44.查找句柄后,再找到edit控件句柄,下面代码测试之前,需要提前打开记事本程序
事先打开笔记本程序,多麻烦,下面这个不需要提前打开笔记本程序,
我们可以这样,在构造函数里,先打开记事本,然后取它的句柄,后面的函数就不需要再查找句柄,
而实例的对象就只对这个记事本窗口操作
由于句柄是唯一的,每次都是对打开的窗口操作,而不影响其它记事本窗口
45. 类的继承
inher是一个新类,我们在它的构造函数里,先实例化想要复制的类,然后用新类的实例化对象this来接收,这种复制就叫做直接继承,新类叫 直接继承的“子类” ,被复制的类在直接继承中叫 “基类"
obj = inher("ok") 实例化子类的时候,子类的构造函数,实际运行是基类的构造函数
复制并修改继承的基类:
this 表示是实例化后的对象,定义的时候不需要使用this,要不会找不到,定义后使用就要(在类里面使用已定义的属性要用this)
46.元表,实际上也是一个表,它的主要作用是里面的元方法,用@操作符后跟一个表,这个表就是一个元表
这里的 owner[k] = "ss" 是设置不是读取,所以不会触发元方法,既然已经设置了,后面再owner[k]时就不是读取不存在的键了,是已经存在的键,所以也不会触发元方法
元表一般不可以修改,而且一个表中只能有一个元表,所以元素名称一般用下划线开头
47. 属性元表就是属性表,属性表使用元表来实现,所以它也是一种元表,只不过封装后使用更方便一些,属性表中的成员在使用上与普通表成员没有什么区别
只不过能自定义读写数据的过程,标准库里应用属性表的地方非常多
属性元表最主要的功能就是能自定义读写数据过程,比如窗口程序的控件属性,大部分都是用他来实现的
就是我们要用到的属性元表,而且名字跟它的库名字一样,最好不要变,前面加上下划线,属性元表只能用于类里面创建
48. 界面设计环节:有些属性是设计时属性,有些是运行时属性,设计时属性是在窗口未显示前设置,运行时属性是可以运行后改变的 winform.static.color=#xxxxx,这个颜色属性就是设计时属性,因为窗口在显示后,一般不会再刷新,如果想要点击某个按钮生效,需要强制刷新一次窗口 :winform.redraw()
49. 使用alt+F4可以关闭窗口
50.
因为消息循环中,会自动按默认操作来处理,比如点关闭按钮,它就会关闭窗口这个默认操作,如果返回false就会阻止这个动作
win.loopMessage();这一句就是启动消息循环,这个循环会自动处理我们操作窗口所产生的消息,来按默认的操作
51.控件(比如button这种)其实也是窗口,控件其实就是窗口的子窗口,有从属关系
52 .
win.getMessagePos(lParam);//有参数
win.getMessagePos();//无参数
不使用参数就是取鼠标屏幕坐标,如果使用参数lparam取的是相对坐标,这时它相对于控件(例如例子使用button右键子窗口)的坐标
53.
控件通知代码,是指一个窗口内的子控件发生了一些事情,需要通知父窗口,这时会向父窗口发送WM_COMMAND或WM_NOTIFY窗口消息,而控件通知代码在这消息的参数中,表示控件发生了那些变化。
54.
55.
time.tick() 取的是系统运行时间,也就是开机到现在的毫秒数
时间戳转日期函数:
56.aardio的编辑器如果不提示,可以按下 ctrl+k来进行提示
一般代码的智能提示会自动出来,也可以按 Ctrl + I ( 或者 Ctrl + J )组合键显示
57.文件操作