Lua之基本语法及数据类型

1.  交互式编程

[root@redis_server_194 lua-5.3.0]# lua -i
Lua 5.3.0  Copyright (C) 1994-2015 Lua.org, PUC-Rio
> print("liudehua")
liudehua 

2.  脚本式编程

    1.  创建一个以lua为后缀的文件,内容如下:

        print("hello world")

    2.  执行一下这个脚本

        lua 1.lua

    3.  完整的文件内容       

#!/usr/local/bin/lua
print("hello world")

        给文件添加执行权限,可以直接执行/root/1.lua

3.  注释

    1.  单行注释

        两个减号

    2.  多行注释

--[[
  aaa
  bbb
]]--

4.  关键词

and break do else
elseif end false for
function if in local
nil not or repeat
return then true until
while goto  

5.  全局变量   

> print(b)
nil
> b=10
> print(b)
10

删除一个全局变量
b = nil
print(b)      --> nil

6.  Lua数据类型

数据类型描述
nil 这个最简单,只有值nil属于该类,表示一个无效值(在条件表达式中相当于false)。
boolean 包含两个值:false和true。
number 表示双精度类型的实浮点数
string 字符串由一对双引号或单引号来表示
function 由 C 或 Lua 编写的函数
userdata 表示任意存储在变量中的C数据结构
thread 表示执行的独立线路,用于执行协同程序
table Lua 中的表(table)其实是一个"关联数组"(associative arrays),数组的索引可以是数字、字符串或表类型。在 Lua 里,table 的创建是通过"构造表达式"来完成,最简单构造表达式是{},用来创建一个空表。

    1.  nil

        nil作比较应该加上双引号"        

> type(X)
nil
> type(X)==nil
false
> type(X)=="nil"
true
>              

    2.  boolean  

        Lua 把 false 和 nil 看作是 false,其他的都为 true,数字 0 也是 true

print(type(true))
print(type(false))
print(type(nil))
 
if false or nil then
    print("至少有一个是 true")
else
    print("false 和 nil 都为 false")
end

if 0 then
    print("数字 0 是 true")
else
    print("数字 0 为 false")
end
结果:
boolean
boolean
nil
false 和 nil 都为 false
数字 0 是 true

    3.  number

print(type(2))
print(type(2.2))
print(type(0.2))
print(type(2e+1))
print(type(0.2e-1))
print(type(7.8263692594256e-06))

    4.  string

        使用单引号或双引号表示,或者[[]]表示一块字符串

        在数字字符串进行算术操作时,Lua尝试将这个数字字符串转成一个数字

> print("2" + 6)
8.0
> print("2" + "6")
8.0
> print("2 + 6")
2 + 6
> print("-2e2" * "6")
-1200.0

        1.  字符串操作

            1.  字符串转换为大写字母

                > string.upper("agc");

                AGC

            2.  字符串转换为小写字母

                > string.lower("DFDE")

                dfde

            3.  字符串替换

                > string.gsub("yangjianbo","yang","liu",3);

                liujianbo

                完整原型:

                  string.gsub (s, pattern, repl [, n])

                  s:  原始字符串

                  pattern:  要查找的模式(可以是普通字符串或正则模式)

                  repl:  替换成的内容

                  n:  最多替换几次

            4.  字符串的索引位置

                > string.find("yangjianbo",'bo',2)

                9 10

                完整原型:

                  string.find (s, pattern [, init [, plain]])

                  s:  要搜索的字符串

                  pattern:  要匹配的模式(可以是普通字符串或lua模式串)

                  init:  从字符串的哪个位置开始搜索(默认1)

                  plain:  如果为true,则关闭模式匹配,只做普通字符串查找

            5.  字符串反转

                > string.reverse("yang")

                gnay

            6.  格式化字符串

                > string.format("fdsfsdf  %s",4)

                fdsfsdf

| 占位符 | 说明 | 示例 |
| ----------- | --------------- | ------------------------------------------------------ |
| `%s` | 字符串 | `string.format("hello %s", "world")` → `"hello world"` |
| `%d` | 整数(十进制) | `string.format("num = %d", 42)` → `"num = 42"` |
| `%i` | 整数(十进制,和 %d 类似) | 同上 |
| `%f` | 浮点数 | `string.format("%.2f", 3.14159)` → `"3.14"` |
| `%e` / `%E` | 科学计数法 | `string.format("%e", 314159)` → `"3.141590e+05"` |
| `%x` | 十六进制(小写) | `string.format("%x", 255)` → `"ff"` |
| `%X` | 十六进制(大写) | `string.format("%X", 255)` → `"FF"` |
| `%o` | 八进制 | `string.format("%o", 9)` → `"11"` |
| `%%` | 输出 `%` 本身 | `string.format("100%%")` → `"100%"` |

            7.  字符串长度

                > string.len("aaa")

                3

            8.  复制字符串

                > string.rep("dsfs",5)

                dsfsdsfsdsfsdsfsdsfs

            9.  链接两个字符串..

                > print("sdfds".."dddd")

                sdfdsdddd                         

        2.  字符串截取

            string.sub(s, i [, j])

            s:  要截取的字符串

            i:  截取开始位置

            j:  截取结束位置,默认为-1,最后一个字符   

-- 字符串
local sourcestr = "prefix--runoobgoogletaobao--suffix"
print("\n原始字符串", string.format("%q", sourcestr))

-- 截取部分,第4个到第15个
local first_sub = string.sub(sourcestr, 4, 15)
print("\n第一次截取", string.format("%q", first_sub))

-- 取字符串前缀,第1个到第8个
local second_sub = string.sub(sourcestr, 1, 8)
print("\n第二次截取", string.format("%q", second_sub))

-- 截取最后10个
local third_sub = string.sub(sourcestr, -10)
print("\n第三次截取", string.format("%q", third_sub))

-- 索引越界,输出原始字符串
local fourth_sub = string.sub(sourcestr, -100)
print("\n第四次截取", string.format("%q", fourth_sub))

    5.  table

        默认初始索引从1开始

        最简单构造表达式{},用来创建一个空表。也可以在表里添加一些数据,直接初始化表

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
结果:
key : value
10 : 33

        1.  table的构造           

-- 初始化表
mytable = {}

-- 指定值
mytable[1]= "Lua"

-- 移除引用
mytable = nil
-- lua 垃圾回收会释放内存

        2.  例子      

-- 简单的 table
mytable = {}
print("mytable 的类型是 ",type(mytable))

mytable[1]= "Lua"
mytable["wow"] = "修改前"
print("mytable 索引为 1 的元素是 ", mytable[1])
print("mytable 索引为 wow 的元素是 ", mytable["wow"])

-- alternatetable和mytable的是指同一个 table
alternatetable = mytable

print("alternatetable 索引为 1 的元素是 ", alternatetable[1])
print("mytable 索引为 wow 的元素是 ", alternatetable["wow"])

alternatetable["wow"] = "修改后"

print("mytable 索引为 wow 的元素是 ", mytable["wow"])

-- 释放变量
alternatetable = nil
print("alternatetable 是 ", alternatetable)

-- mytable 仍然可以访问
print("mytable 索引为 wow 的元素是 ", mytable["wow"])

mytable = nil
print("mytable 是 ", mytable)

        3.  Table操作

                1.  Table连接

                table.concat(table,sep,start,end)      

                sep  分隔符

                start  开始位置

                end  结束位置                           

fruits = {"banana","orange","apple"}
-- 返回 table 连接后的字符串
print("连接后的字符串 ",table.concat(fruits))

-- 指定连接字符
print("连接后的字符串 ",table.concat(fruits,", "))

-- 指定索引来连接 table
print("连接后的字符串 ",table.concat(fruits,", ", 2,3))
结果:
连接后的字符串     bananaorangeapple
连接后的字符串     banana, orange, apple
连接后的字符串     orange, apple

            2.  插入和删除              

fruits = {"banana","orange","apple"}

-- 在末尾插入
table.insert(fruits,"mango")
print("索引为 4 的元素为 ",fruits[4])

-- 在索引为 2 的键处插入
table.insert(fruits,2,"grapes")
print("索引为 2 的元素为 ",fruits[2])

print("最后一个元素为 ",fruits[5])
table.remove(fruits)  移除的是最后一个元素
print("移除后最后一个元素为 ",fruits[5])
结果:
索引为 4 的元素为     mango
索引为 2 的元素为     grapes
最后一个元素为     mango
移除后最后一个元素为     nil

            3.  排序

                对给定的table进行升序排序

fruits = {"banana","orange","apple","grapes"}
print("排序前")
for k,v in ipairs(fruits) do
        print(k,v)
end
要查看table的所有键值,需要自己遍历
table.sort(fruits) print("排序后") for k,v in ipairs(fruits) do print(k,v) end
结果:
排序前
1    banana
2    orange
3    apple
4    grapes
排序后
1    apple
2    banana
3    grapes
4    orange

            4.  Table最大值                

function table_maxn(t)
  local mn=nil;
  for k, v in pairs(t) do
    if(mn==nil) then
      mn=v
    end
    if mn < v then
      mn = v
    end
  end
  return mn
end
tbl = {[1] = 2, [2] = 6, [3] = 34, [26] =5}
print("tbl 最大值:", table_maxn(tbl))
print("tbl 长度 ", #tbl)
结果:
tbl 最大值:    34
tbl 长度     3                                    

    6.  function

        函数是被看作是"第一类值(First-Class Value)",函数可以存在变量里       

function factorial1(n)
    if n == 0 then
        return 1
    else
        return n * factorial1(n - 1)
    end
end
print(factorial1(5))
factorial2 = factorial1
print(factorial2(5))
结果:
120
120

function testFun(tab,fun)
        for k ,v in pairs(tab) do
                print(fun(k,v));
        end
end


tab={key1="val1",key2="val2"};
testFun(tab,
function(key,val)--匿名函数
        return key.."="..val;
end
);
结果:
key1 = val1
key2 = val2

    7.  thread

        在 Lua 里,最主要的线程是协同程序(coroutine)。它跟线程(thread)差不多,拥有自己独立的栈、局部变量和指令指针,可以跟其他协同程序共享全局变量和其他大部分东西。

        线程跟协程的区别:线程可以同时多个运行,而协程任意时刻只能运行一个,并且处于运行状态的协程只有被挂起(suspend)时才会暂停。

    8.  userdata

        userdata 是一种用户自定义数据,用于表示一种由应用程序或 C/C++ 语言库所创建的类型,可以将任意 C/C++ 的任意数据类型的数据(通常是 struct 和 指针)存储到 Lua 变量中调用。

    9.  数组

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

        1.  一维数组

array = {"Lua", "Tutorial"}

for i= 0, 2 do
   print(array[i])
end    

        2.  多维数组

-- 初始化数组
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

      

posted @ 2022-10-17 13:30  奋斗史  阅读(85)  评论(0)    收藏  举报