Lua学习笔记(总结Runoob.com)上

Lua学习笔记(总结Runoob.com)

概述

  • 文章是对Rounoob.com所有的Lua文章进行学习的个人总结笔记,有些是Runoob.com抄写的内容,主要是自己看来一遍,把里面的东西都实现了,然后手打了一遍知识点,进行迁移到这里,由于文章比较长,所以对其进行拆分,这是第一篇。上篇主要内容有编译环境、基本语法数据类型、变量、循环、流程控制、函数、运算符、字符串、数组

一、基础

1、编译环境

  • 使用源码包,并在终端解压编译后即可使用

  • 在windows上面可以直接使用安装包进行安装,安装后得到两个exe,一个是控制台、一个是文本编辑器

2、基本语法

  1. 交互式编程

    • 直接在命令行输入然后直接查看结果
  2. 脚本试编程

    • 使用lua结尾的文件,进行执行即可编译
  3. 注释

    • 单行注释使用--
    • 多行注释--[[多行注释]]
  4. 标识符

    • 标识符用于定义个变量、函数获取其他用户定义的项,由:字母、下划线、数字组成
    • 必须字母或下划线开头
    • 最好不要使用下划线加大写字母,因为Lua保留字也是这样的
    • 不允许出现特殊字符来定义标识符
  5. 关键词

    • 不能作为变量、常量或其他用户自定义标识符
    • 一般约定,以下划线开头链接大写字母的名字(如:_VERSION)被保留用于Lua内部全局变量。
  6. 全局变量

    • 默认情况下,变量都是全局的。

    • 全局变量不需要声明,给变量赋值后即成为全局变量,访问没有初始化的变量也不会报错,只会显示为nil。

    • 如果需要删除一个全局变量直接使它赋值为nil。

    • 当且仅当变量不等于nil时,这个变量即存在

      print(b) -- nil
      b = 10
      print(b)	--10
      b = nil
      print(b)	--nil
      

3、数据类型

  1. Lua是动态类型语言,变量不要类型定义,只需要为变量赋值。值可以存储在变量中,作为参数传递或者结果返回。
  2. Lua中有8种基本类型分别为nil,boolean,number,string,userdata,function,thread,table
数据类型 描述
nil 只有值nil属于该类型,表示一个无效值(在条件表达式中相当于false)
boolean 包含两个值:false和true
number 表示双精度类型的实浮点数
string 字符串类型 由一对引号或单引号来表示
function 由C或Lua编程的函数
userdata 表示任意存储在变量中的C数据结构
thread 表示执行的独立线路,用于执行协同程序
table Lua中的表(table)其实是一个“关联数组(associative arrays),数组的索引可以是数字(索引从1开始),或者是字符串,table的创建是通过”构造表达式“来完成的,最简单的构造表达式是{},用来表示创建一个空表
print(type("Hello world"))      --> string
print(type(10.4*3))             --> number
print(type(print))              --> function
print(type(type))               --> function
print(type(true))               --> boolean
print(type(nil))                --> nil
print(type(type(X)))            --> string
  1. nil 表示一种没有任何有效值,对于全局变量和table来说nil还有一个“删除”的作用,nil作为比较时应该加上“ ”

  2. bolean(布尔),只有两个值true和false,Lua把false和nil看做为“假”

  3. number(数字)默认只有一种类型为double类型,也可以在luaconf.h里面修改默认类型

  4. string(字符串)

    • string (字符串)由一对双引号或单引号来表示,
    • 也可以使用[[表示一块字符串]],在对数字字符串上进行算术操作时,Lua会先尝试将数字字符串转成一个数字,
    • 使用#号来计算字符串长度,放在字符串前面
  5. table(表)

    • 通过“构造表达式”来完成,最简单的构造表达式为{}表示创建一个空表,也可在里面添加数据,直接初始化表

    • 表其实是一个“关联数组”数组的索引可以是数字或者字符串

    • Lua的索引从1开始

    • table不会固定长度,有新数据添加时table长度会自动增长。

      a = {}
      a["key"] = "value"
      key  = 10
      a[key] = 22
      a[key] = a[key] + 11
      for k ,v in pairs(a)do
          print(k.. ":" .. v)
          end
      
  6. function(函数)

    • 函数被看做“第一类值(First_Class Value),函数可以存在变量里
    • function可以是匿名函数(amonymous function)的方式通过参数传递

二、变量、循环、流程控制

1、变量

  1. 变量在使用前,必须在代码中进行声明,即创建变量

  2. 编译程序执行代码之前编译器需要知道如何给语句变量开辟存储区,用于存储变量

  3. Lua变量有三种:全局变量、局部变量、表中的域。

  4. Lua中的变量全是全局变量,语句块或者函数里也是,除非用local显示声明为局部变量。

  5. 局部变量的作用域为从声明位置开始到语句块结束。

  6. 变量默认值为nil

    a = 5 			--全局变量
    local a = 5		--局部变量
    function joke()
        c =5		--全局变量
        local d = 6	--局部变量
       end
    joke()
    print(c,d)		-->5 nil
    do
        local a = 6		--局部变量
        b = 6			--对局部变量重新赋值
        print(a,b);		-->6 6
        end
    print(a,b)		-->5 6
        
    
  • 赋值语句

    • 赋值是改变一个变量的值和改变表域的最基本的方法a = "hellow" .. "world" ; t.n = t,n +1

    • 也可以对多个变量同时赋值,变量列表和值列表的各个元素用逗号分开,赋值语句会依次赋给左边的变量

      a,b = 10,2x		-->a = 10;b =2*x
      
    • 遇到赋值语句会计算右边所有的值,然后在执行赋值操作。

      x,y = y,x			--swap 'x' for 'y' 
      a[i],a[j] = a[j]a[i] 	--swap'a[i]' for 'a[j]'
      
    • 当变量个数不一致的时候,会以变量个数为基础采取

      A、变量个数 > 值的个数		按变量个数不足nil
      B、变量个数 < 值的个数		多余的值会被忽略
      
    • 多值赋值经常用来交换变量,或将函数调用返回变量a,b = f()f()返回两个值,第一个赋值给a,第二个赋值给b,

    • 应该尽可能的使用局部变量,

      • 可以避免命名冲突
      • 访问局部变量的速度比全局变量更快
  • 索引

    • 对于table的索引使用方括号[]

      t[i]
      t.i		--当索引为字符串类型的时的一种简化写法
      gettable_event(t,i)		--采用索引访问本质上是一个类似这样的函数调用
      

2、循环

循环类型 描述
while循环 在条件为true时,让程序重复执行某些语句,执行语句前会先检查条件是否为true
for循环 重复执行指定语句,重复次数可在for语句中控制
repeat …until 重复执行循环,知道指定条件为真时为止
嵌套循环 可以在循环内嵌套一个或多个循环语句(while do,for do end,repeat…unitl
  1. while循环

    • while 循环语句在判断条件为 true 时会重复执行循环体语句。
    while(condition)		--condition(条件)可以是任意表达式,在condition为true时执行循环体
    do
        statements 	--	可以是一条或者多条语句
    end
    -- condition为false时会跳过当前循环并开始执行end后面的语句
    
  2. for循环

    • 主要分为数值for循环和泛型for循环

      • 数值型for循环
      for var = exp1,exp2,exp3 do -- var从从 exp1 变化到 exp2,每次变化以 exp3 为步长递增 var,并执行一次 "执行体"。exp3 是可选的,如果不指定,默认为1。
          <执行体>
      end
      -- 三个表达式在循环开始前一次性求值,以后不再进行求值,
      
      • 泛型for循环
        • 泛型for循环通过一个迭代器函数来遍历所有值,类似C#里面的foreach语句
      -- 打印数组a的所有值
      a {"one","two","three"}
      for i,v in ipairs (a)do		--	i是数组索引值,v是对于索引的数组元素值,ipairs是lua提供的一个迭代函数,用来迭代数组
          print(i,v)
          end
      
  3. Lua repeat…until 循环

    • repeat…until 循环语句不同于 for 和 while循环,for 和 while 循环的条件语句在当前循环执行开始时判断,而 repeat…until 循环的条件语句在当前循环结束后判断。类似C# do while
    repeat
    stantements
    until(condition)   --判断condition在末尾,所以在条件进行判断前循环体都会执行一次,若果条件条件判断语句(condition)为 false,循环会重新开始执行,直到条件判断语句(condition)为 true 才会停止执行。
    
  4. 嵌套循环

    • for循环嵌套语法

      for init,max/min value,increment
      do
          for init,max/min value,increment
          do
              statements
              end
          statements
          end
      
    • while循环嵌套循环

      while(condition)
      do
          while(condition)
          do
              statements
              end
          statements
          end
      
    • repeat…until循环嵌套语法

      repeat
          statements
          repeat
              statements
              until(condition)
          until(condition)
      
    • 当然也可以三个循环中不同之间的嵌套也是可以的

  5. 循环控制语句

    • 用于控制程序的流程,以实现程序的各种结构方式

      控制语句 描述
      break语句 退出当前循环或语句,并开始脚本执行紧接着的语句
  6. 无限循环

    • 循环体一直执行

      while(true)
      do
          print("循环将永远执行下去")
          end
      

3、流程控制

  1. 条件为 true 时执行指定程序代码,在条件为 false 时执行其他指定代码。Lua认为false和nil为假,true和非nil为真。**在Lua中0为true。

    语句 描述
    if语句 if 语句 由一个布尔表达式作为条件判断,其后紧跟其他语句组成。
    if…else语句 if 语句 可以与 else 语句搭配使用, 在 if 条件表达式为 false 时执行 else 语句代码。
    if嵌套语句 你可以在ifelse if中使用一个或多个 ifelse if 语句 。

三、函数、运算符、字符串、数组

1、函数

  1. 函数是对语句和表达式进行抽象的主要方法,可以用来做一些特殊处理,也可以计算一些值

  2. 主要有两个用图

    • 完成指定的任务,这种情况下函数作为语句使用

    • 计算并返回值,这种情况下函数作为赋值语句和表达式使用

      -- 函数的定义格式如下
      optional_function_scope function function_name(argument1,argument2,argument3....,atgumentn)
          function_body
          return result_oprams_comma_separated
          end
      -- optional_function_scope:该产生是可选的指定函数是全局函数还是局部函数,未设置的时候默认为全局函数,如果需要设置为局部函数则使用local
      -- function_name:指定函数的名字
      --argument1,argument2,argument3....,atgumentn:函数参数,用逗号隔开,可以不设置
      -- result_oprams_comma_separated:函数返回值,可以多个返回值,每个用逗号隔开
      --我们还可以将函数作为参数传递给函数
      
  3. 多返回值

    • 可以返回多个值,如果有些值不存在则返回nil
  4. 可变参数

    • 在函数列表中使用三个点…表示函数有可变的参数

    • 我们也可以将函数赋值给一个变量

    • 同时也可以通过select(“#”,…)来获取可变函数的数量

    • 我们可能需要几个固定参数加上可变参数,固定参数必须放在可变参数之前

    • 通常在遍历变长参数的时候只需要使用 {…},然而变长参数可能会包含一些 nil,那么就可以用 select 函数来访问变长参数了:**select(’#’, …)**或者 select(n, …)

      • select(’#’, …) 返回可变参数的长度
      • select(n, …) 用于访问 nselect(’#’,…) 的参数
    • 调用select时,必须传入一个固定实参selector(选择开关)和一系列变长参数。如果selector为数字n,那么select返回它的第n个可变实参,否则只能为字符串"#",这样select会返回变长参数的总数

2、运算符

  1. 主要分为:算术云算符、关系运算符、逻辑云算符、其他运算符

  2. 算法云算符

    操作符 描述 实例
    + 加法 A + B 输出结果 30
    - 减法 A - B 输出结果 -10
    * 乘法 A * B 输出结果 200
    / 除法 B / A w输出结果 2
    % 取余 B % A 输出结果 0
    ^ 乘幂 A^2 输出结果 100
    - 负号 -A 输出结果v -10
  3. 关系运算符

    操作符 描述 实例
    == 等于,检测两个值是否相等,相等返回 true,否则返回 false (A == B) 为 false。
    ~= 不等于,检测两个值是否相等,相等返回 false,否则返回 true (A ~= B) 为 true。
    > 大于,如果左边的值大于右边的值,返回 true,否则返回 false (A > B) 为 false。
    < 小于,如果左边的值大于右边的值,返回 false,否则返回 true (A < B) 为 true。
    >= 大于等于,如果左边的值大于等于右边的值,返回 true,否则返回 false (A >= B) 返回 false。
    <= 小于等于, 如果左边的值小于等于右边的值,返回 true,否则返回 false (A <= B) 返回 true。
  4. 逻辑运算符

    操作符 描述 实例
    and 逻辑与操作符。 若 A 为 false,则返回 A,否则返回 B。 (A and B) 为 false。
    or 逻辑或操作符。 若 A 为 true,则返回 A,否则返回 B。 (A or B) 为 true。
    not 逻辑非操作符。与逻辑运算结果相反,如果条件为 true,逻辑非为 false。 not(A and B) 为 true。
  5. 其他运算符

    操作符 描述 实例
    连接两个字符串 a…b ,其中 a 为 "Hello " , b 为 “World”, 输出结果为 “Hello World”。
    # 一元运算符,返回字符串或表的长度。 #“Hello” 返回 5
  6. 运算符优先级

    • 终极法则——加括号

3、字符串

1、三种表现

  • 单引号间的一串字符。

  • 双引号间的一串字符。

  • [[和]]间的一串字符。

  • 转义字符

    转义字符 意义 ASCII码值(十进制)
    \a 响铃(BEL) 007
    \b 退格(BS) ,将当前位置移到前一列 008
    \f 换页(FF),将当前位置移到下页开头 012
    \n 换行(LF) ,将当前位置移到下一行开头 010
    \r 回车(CR) ,将当前位置移到本行开头 013
    \t 水平制表(HT) (跳到下一个TAB位置) 009
    \v 垂直制表(VT) 011
    \ 代表一个反斜线字符’’’ 092
    代表一个单引号(撇号)字符 039
    " 代表一个双引号字符 034
    \0 空字符(NULL) 000
    \ddd 1到3位八进制数所代表的任意字符 三位八进制
    \xhh 1到2位十六进制所代表的任意字符 二位十六进制

2、字符串操作

方法 用途
string.upper(argument) 字符串全部转为大写字母
string.lower(atgument) 字符串全部转为小写字母
string.gsub(main String,find String,replace String ,num) 在字符串中替换mainString为要替换的字符串,findString为被替换的字符,replaceString要替换的字符串,num替换的次数(可忽略,则为替换全部)
string.find (str, substr, [init, [end]]) 在一个指定的目标字符串中搜索指定的内容(第三个参数为索引),返回其具体位置。不存在则返回 nil。
string.reverse(arg) 字符串翻转
string.format(…) 返回一个类似printf的格式化字符串
string.char(arg) 和 string.byte(arg[,int]) char 将整型数字转成字符并连接, byte 转换字符为整数值(可以指定某个字符,默认第一个字符)。
string.len(arg) 计算字符串长度。
string.rep(string, n) 返回字符串string的n个拷贝
链接两个字符串
string.gmatch(str, pattern) 回一个迭代器函数,每一次调用这个函数,返回一个在字符串 str 找到的下一个符合 pattern 描述的子串。如果参数 pattern 描述的字符串没有找到,迭代函数返回nil。
string.match(str, pattern, init) string.match()只寻找源字串str中的第一个配对. 参数init可选, 指定搜寻过程的起点, 默认为1。
在成功配对时, 函数将返回配对表达式中的所有捕获结果; 如果没有设置捕获标记, 则返回整个配对字符串. 当没有成功的配对时, 返回nil。

3、字符串格式化

  • 跟C语言中的printf()类似

4、匹配模式

  • 用于模式匹配函数 string.find, string.gmatch, string.gsub, string.match。

    你还可以在模式串中使用字符类。

  • 详细的查看Runoob.com

5、三个实用字符串操作


--阿拉伯站位汉字
local function NumToCN(num)
    local size = #tostring(num)
    local CN = ""
    local StrCN = {"一","二","三","四","五","六","七","八","九"}
    for i = 1 , size do
        CN = CN .. StrCN[tonumber(string.sub(tostring(num), i , i))]
    end
    return CN
end
print(NumToCN(56665))
-- 移除中文
--function StrSplit(inputstr,sep)
function StrSplit(inputstr, sep)
	if sep == nil then
	sep = "%s"
	end
	local t = {}
	local i = 1
for str in string.gmatch(inputstr,"([^"..sep.."]+)")do
t[i] = str
i = i+1
end
return t
end
local a = "312343242,莫莫"
local b = ":"
b = StrSplit(a,",")
print(b[1])


-- 去除字符串首位的空格
function trim(s)
return (string.gsub(s,"^%s*(.-)%s*$","%1"))
end
string6 = "     Runoob"
string7 = trim(string6)
print (string7)

4、数组

1、相同数据类型的元素按一定顺序排列的集合,可以是一维数组和多维数组

  • 数组的索引键值可以只用整数表示,数组的大小是不固定的

2、一维数组

  • 一维数组的逻辑结构是线性表,可以用for循环读取里面所有的数据

  • 数组索引从1开始,但是也可以手动设置为0开始,也可以动态的赋值,从负数开始也可以

    array = {}
    for i = -2,2 do
        array[i] = i *2
        end
    for i = -2,2 do
        print(array[i])
        end
    

3、多维数组

  • 数组中包含数组或者一维数组的索引键对应一个数组

    --初始化数组
    array = {}
    for i = 1,3 do
        array[i] = {}
        for j = 1, 3 do
            array[i][j] = i*j
            end
        end
    --访问数组
    for i = 1, 3 do
        for j =1,3 do
            print(array[i][j])
            end 
        end
    --不同索引键的三行三列阵多维数组
    --初始化数组
    array1 = {}
    maxRows = 3
    maxColumns = 3
    for row = 1,maxRows do
        for col =1 ,maxColumns do
            array1[row*maxColumns + col] = row * col
            end
        end
    --访问数组
    for row = 1,maxRows do 
        for col = 1, maxColumns do
            print (array1[row*maxColumns + col])
            end
        end
    
    
    
    • 上面最后一个实例中,数组设定了指定的索引值,这样可以避免出现nil值,有利于节省内存空间

猜你喜欢

转载自blog.csdn.net/Momorey/article/details/85003216