数据类型

一、变量

 在脚本运行过程中,用来存储数据值并且其值能被改变的量称为变量。变量的名称用字母、数字、中文字符、下划线等组成的标识符来表示。

请看下面的代码

win.consoleOpen(); --打开控制台窗口
 
local str = "字符串"; --声明一个局部变量,存储字符串类型的值
str = "字符串2"; --变量的值是可以改变的
 
local n = 32; --声明一个变量,存储数字类型的值
n = 64; --变量的值是可以改变的
 
_str = "全局字符串"; --如果没有用local语句声明的变量,默认就是全局变量
_str = "全局字符串2"; --变量的值也是可以改变的



str 与 n虽然都是变量,但是他们存储的是不同类型的数据,下面我们讲数据类型。

二、数据类型


LAScript一共有8种基本类型:nil, boolean, number, string, userdata, function, thread, table.


type函数返回一个变量或数据的数据类型

win.consoleOpen();
 
print(  type(nil)  );            -->显示 nil
print(  type("Hello world")  )-->显示 string
print(  type(1000)  );           -->显示 number
print(  type(print)  );          -->显示 function
print(  type(true)  );           -->显示 boolean
print(  type( image.new() )  )-->显示 userdata
print(  type( {x=0,y=0} )  );    -->显示 table

LAScript是动态语言,变量的数据类型不需要声明并且可以随时改变

v = "字符串";
v = 1000; --变量的数据类型被改变了
 
v = "10";
a = v +1; --字符串类型的v自动转换为数字参与数学运算,结果 a == 11
 
b = a.."abc"; --数字类型的a自动转换为字符串进行连接,结果 b == "11abc"

 

1、nil 空值、没有定义的变量

nil即变量没有存储任何数据,将一个变量赋值为nil等于删除这个变量

2、boolean 逻辑布尔值

有两个值,truefalsetrue为真,false为假,通常用在条件判断语句中。
通俗一点说,true表示是、符合条件,false表示不是、不符合条件。

如果将其他类据类型转换为boolean值,除nil被认为是false以外,其他有效的数据都被认为是true;
这与C++有所不同,C++认为0是false非零是true,但是在LAScript中,0也被认为是true;

LAScript提供了几个用于API函数的常量: _TRUE 表示非零,_FASLE表示零,_NULL表示零

3、number 数值

数值类型可用十进制的数赋值,例: num = 12.2222;
也可以用十六进制的数赋值,0x表示后面是一个十六进制的数,例:num = 0xA1 + 0xFF
或用科学计算法表示 a = 6e+20

把一个大于10的数写成a * 10n 的形式,其中a是整数数位只有一位的数,这种计数法叫做科学计数法,也叫10的幂计数法。例如 a= -3.5×105 这里最前面有一个负号,3.5是尾数,两个有效数字,后面以10为基数的指数为5。我们可以将它表示为-3.5E5。


4、string 字符串(与其他编程语言不同,string可以帮含二进制数据,即允许包含\0)

字符串被放在引号中 例:str ="字符串" 或 str ='字符串'
字符串支持转义字符,与C++相同 例:

\a 响铃符(常用于print函数发出警告铃声,例如 print("\a")
\b 退格
\f 换页
\n 换行
\r 回车
\t 制表符(横向跳格)
\v 匹配一个垂直制表符。等价于 \x0b
\\ 反斜杠字符\
\" 双引号
\' 单引号
\[ 方括号[
\] 方括号]
\x 用x后面的十六进制表示一个字符


字符串中也可以直接用十六进制表示字符,例:
print("Hel\x6c\x6f world\x21")

字也可以直用三位十进制数表示字符,格式如\000 例:
print("Hel\108\111 world\33")



所以通常要写样写文件路径 path = "c:\\目录\\文件名.txt"

如果你不想使用转义符,可以把字符串放在两个方括号中间,而且可以换行,例

str = [[
这是一个字符串
这是字符串
]]

您可以在开始标记[[ 以及 结束标记]]中间加入相同数目的等号。 例如:

str = [===[
这是一个字符串,这里就可以使用[[ 或者 ]]了
这是字符串
]====]

字符串如果包含双引号则应放在单引号中,或者放在[[ ]] 中间,
如果放在双引号中则必须加上\转义符.

str =" a =\"abcd\" "; --正确
str =' a ="abcd" '; --正确
str =[[ a ="abcd" ]]; --正确

str =" a ="abcd"] "; --错误的写法

 

字符串连接用 .. 操作符。数字在使用..连接符连接时会自动转换为字符串
str = "2"..20; --str等于"220",20自动换为字符串并进行字符串连接;
n = "2"+ 20; --n等于22,"2"是字符串,参与数学运算时自动转换为数字2
 
n = tonumber("2"); --tonumber函数强制转换一个变量为数字,如果失败返回nil空值
str = tostring(2); -- tostring函数强年转换一个变量为字符串。

n = "abc" + 20; --出错,"abc"无法自动转换为数字
n = "2" + 20; --正确,参与数学运算的字符串必须是有效数字格式。
 
str = 20.."abc"; --出错,..连接符中的第一个圆点紧跟在数字后面被认为是小数点
str = 20 .. "abc"; --正确,在数字后面加一个空格 

 

5、table 列表

什么是table:
table是LAScript最重要的数据类型,可以存储复杂的数据结构。
table可以存储任意多个元素,每个元素都是一个“键值对”。“键”可以是字符或其他附nil以外的数据类型,甚至可以在table元素中包含table,table允许嵌套。

通常把“键”放在索引操作符“[]”中来索引一个元素的值,这时候键又称为“下标”。例如 tab["键"] tab[1] ;
也可以把一个符合变量命名规则的键放在成员操作符“.”后面,这时候键又称为“公用成员”。例如 tab.key tab.key2 ;
什么是table字典:
table中的所有元素都是键值对,table本身就是一个“字典(Dictionaries)”.在某些语言中可能称为“映射(Map)”、“联合内存(associative memories)”或“联合数组(associative arrays)”,字典的是无序的键值对(key:value pairs )集合,键是互不相同的(在同一个字典之内)。
什么是table数组:
字典中所有以数字索引作为键的元素构成数组。数组是有序的

 使用{}构造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"}

--point.x 的值是100;point.y 的值是200

table的键名并不要求符合变量命名规则,键可以是任何除nil以外的值或字符串。
但是在{}构造器中的键名必须符合变量命名规则。

因为在{}构造器中的键名必须符合变量命名规则,很显然这样的写法是错的:
tab = {1=300,2=400,+=200,1+1=200}; --因为变量名不能以数字开始,更不能包含运算符。


如果我们需要在构造器中使用不规则的键,需要使用下标操作符[]。

在任何时候,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中的元素时,用元素的键作为下标查询元素的值,例如:

tab = {}; --用一对花括号创建一个空的table
tab["x"] = 200; --下标为字符串"x",键名为字符串"x",值为数值200。
tab[1] = "hellor world"; --下标为数字1,键索引为1,值为字符串 "hellor world"


如果“键”是一个数字索引称为“键索引”,如果键是一个字符串称为“键名” ,
对于符合变量命名规范的键名,可以用"."成员符访问。例如:
tab["x"] = 200; 也可以写为 tab.x = 200;



当我们将tab元素赋值为nil会删除这个元素。例如: tab.x = nil; --删除tab成员x 。

我们可以把多个变量用一对花括号包含起来以转换为table列表,也可以通过unpack函数将table转换为多个变量。
--例如 wb:eleLinks() 返回多个数目不定的网页超链接对象
twnd= { win.fromFile(win.getExeFile()) };--将所有返回值转换为table变量tlinks

tab = {"a","abc","abcd"} ;--创建一个table;
a,b,c = unpack(tab);

遍历table列表中的全部元素
win.consoleOpen();--打开控制台窗口,用来支持print函数
tab = {a="字符串", b= 123,c="字符串2",d=23,e=56,78,99,123,0}

for
k,v in pairs(tab) do
    --k为键,v是匹配的值,在这里键值对无序的随机出现。 
    print(k,v); -->显示: 键,值
end;

遍历table列表中的数组元素

win.consoleOpen();--打开控制台窗口,用来支持print函数
tab = {"字符串", 123,"字符串2",23,56,78,99,123,0,test=123};--tab.test不是数组元素

for i,v in ipairs(tab) do
    --i为键,v是匹配的值,在这里键值对有序的出现。
    print(i,v); -->显示: 数字索引,数组元素的值
end;

获取table列表中的下一个元素

next函数通常用在「fap模拟程序」中「周而复始」的循环遍历table对象,
请参考链接: next函数
6、function 函数类型,函数也是一种变量,所以你可以重新定义任何函数。


7、userdata 对象

对象是由模拟精灵提供的特殊数据类型,可以象table一样使用,有成员变量、成员函数等。

例如在fap模拟程序中,“模拟区块”的数据类型就是 Userdata
local m = ape:getModule("模拟区块名")
win.messageBox(type(m))

8、thread 协同线程类型

thread是协同线程中使用的数据类型。与win.exec创建的多线程无关。

三、转换数据类型

1、类型转换

数值、字符串会自动转换,但是我们也可以用LAScript提供的函数强制转换。

n = tonumber("2");
--tonumber函数强制转换一个变量为数字,如果失败返回nil空值
str = tostring(2);
-- tostring函数强年转换一个变量为字符串。

2、进制转换

--数字转换为二进制字符串
str = string.format("%b",23 );
 
--二进制字符串转换为数字
n = tonumber(str,2)
 
--数字转换为八进制字符串
str = string.format("%o",23 );
 
--八进制字符串转换为数字
n = tonumber(str,8)
 
--数字转换为十六进制字符串
str = string.format("%x",23 );
 
--十六进制字符串转换为数字
n = tonumber(str,16)