前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >自学成菜-流水账学习法lua入门

自学成菜-流水账学习法lua入门

作者头像
用户2825413
发布2019-07-15 17:47:46
9910
发布2019-07-15 17:47:46
举报
  • 学习背景: 一直想去体验下openrestry,可惜一直没动力去完成这件事,正好工作原因需要调研,就开启体验之旅吧。开始前需要对lua语法有简单了解和认识
  • 流水式计划:
    • 基础语法简单熟悉
    • openrestry模块知识点实践
    • 一个小项目
  • 致谢码洞公众号老钱界面排版经验传授

lua基础语法

代码语言:javascript
复制
print("hello lua")

获取数据类型 函数type

代码语言:javascript
复制
a = 123
print(type(a))     -->output:number
print(type(1.23))  -->output:number
print(type(nil))   -->output:nil
print(type('123')) -->output:string
print(type(true))  -->output:boolean

a = {}
print(type(a))     -->output:table

local b
print(b)        -->output:nil  默认nil
代码语言:javascript
复制
  以上出现了几个关键词简单描述下:
  1. local相当于声明变量b为局部变量
  2. --为单行注释 --[[ code ]]为多行注释
代码语言:javascript
复制
local a = 0

if a then
   print('pass')  --output:pass
end
代码语言:javascript
复制
local b
if b then
   print('pass')
else
   print('no pass') --output:no pass
end
代码语言:javascript
复制
local a=false

if a then
   print('pass')
else
   print('no pass') --output:no pass
end

在lua中,nil和false为假,其他所有值为真 比如0和空字符串都为真

代码语言:javascript
复制
local a = 5
local b = 3

function getNumber()
    if a>b then
        return a
    else
        return b
    end
end

value = getNumber()
print(value)

声明a,b两个全局变量,声明了一个函数返回最大值,其中需要注意的就是lua是没有函数提升的概念的,所以需要先声明后使用

代码语言:javascript
复制
local a = 5
local b = 3

function getNumber(a,b)
    if a>b then
       return a
    else
       return b
    end
end

value = getNumber(a,b+3) 
print(value) //output:6
代码语言:javascript
复制
local a = 5
local b = 3

function getNumber()
    local b = 10
    if a>b then
       return a
    else
       return b
    end
end

value = getNumber()
print(value)   --output:10 

函数中的b作用于函数块内,覆盖外部b的变量值


Math函数库

代码语言:javascript
复制
a = 1.2

print(math.floor(a)) --output : 1

print(math.ceil(a))  --output : 2

print(math.abs(a))   --output : 1.2

print(math.random(20,30)) --output : 随机

print(math.max(1,2,3,4,8,5,0)) --output : 8

print(math.min(1,2,3,4,8,5,0)) --output : 0

lua并没有四舍五入,如果实现可以使用math.floor

代码语言:javascript
复制
lua 中的math.floor函数是向下取整函数。
    math.floor(5.123)   -- 5
    math.floor(5.523)   -- 5
用此特性实现四舍五入
    math.floor(5.123 + 0.5)  --5
    math.floor(5.523 + 0.5)  --6
也就是对math.floor函数的参数进行 “+ 0.5” 计算

String函数库

代码语言:javascript
复制
s = 'abcd123'

print(string.len(s))  --output : 7

print(string.rep(s,2)) --output : abcd123abcd123

print(string.lower(s)) --output : abcd123

print(string.upper(s)) --output : ABCD123

print(string.sub(s,1,2)) --output : ab

local find = string.find
print(find('abcd haha 123','a',2)) --output:7
print(find('abcd haha 123','az',2)) --output:nil

print(string.format('%d',2.5 )) --output : 2

print(string.format("%.2f",1.256)); --output : 1.26

print(string.format('value: %s',s )) --output : value: abcd123

注意 string.sub 从1开始截取,截取2个字符。lua下标是从1开始的 %.2f也可以实现四舍五入

新类型-强大的talbe

代码语言:javascript
复制
local user = {
   name = "xiao ge ge",
   age  = {
     1,2,3
   }
}

print(user.name) --output : xiao ge ge

print(user.age[1]) --output : 1

local class = {'one class','two class'}

print(class[0]) --output : nil

print(class[1]) --output : one class

day1 = {2018,7,1,0,0,0}
print(#(day1)) --获取长度 6
print(table.getn(day1)) --获取长度 6
print(next(day1)) --验证是否为空
table函数库
代码语言:javascript
复制
tbl = {"alpha", "beta", "gamma"}

print(table.concat(tbl, ":"))   --output: alpha:beta:gamma

print(table.concat(tbl, nil, 1, 2)) --output: alphabeta

print(table.concat(tbl, "\n", 2, 3)) --output: beta \n gamma
代码语言:javascript
复制
tbl = {"a", "b", "c"}

table.insert(tbl, "d")

print(table.concat(tbl,",")) --output: a,b,c,d

table.insert(tbl, "e") 

print(table.concat(tbl,",")) --output: a,b,c,d,e
代码语言:javascript
复制
class = {1,2,3,4,5}
max = table.maxn(class);
print(max)   --output: 5
代码语言:javascript
复制
class = {1,2,3,4,5,6}
max = table.remove(class); 
print(max) --output: 6
print(table.concat(class,',')) --1,2,3,4,5

remove相当于其他语言的pop,移除最后一位

入栈 出栈操作

代码语言:javascript
复制
list = {'a','b','c'}

table.insert(list,'d');  --进栈

print(table.concat(list,',')) --a,b,c,d

table.remove(list)  --出栈

print(table.concat(list,',')) --a,b,c

队列操作

代码语言:javascript
复制
list = {'a','b','c'}

table.insert(list,1,'1'); --入队列 注意下标1

print(table.concat(list,',')) --1,a,b,c

table.remove(list)  --出队列

print(table.concat(list,',')) --1,a,b
日期时间函数

uninx时间戳

代码语言:javascript
复制
print(os.time()) --output : unix时间戳

day1 = {year=2018,month=7,day=1,hour=0,min=0,sec=0}
day1_time = os.time(day1) --output: 获取day1时间戳

day2 = {year=2018,month=7,day=1,hour=0,min=1,sec=0}
day2_time = os.time(day2)

print(os.difftime(day1_time,day2_time)) --day1-day2=-60

时间戳转时间

代码语言:javascript
复制
    temp = os.date("*t", 906000490)
    --{year = 1998, month = 9, day = 16, yday = 259, wday = 4,hour = 23, min = 48, sec = 10, isdst = false}

    date = os.date('%Y-%m-%d %H:%M:%S',os.time())
    print(date)  --output: 2018-07-01 06:19:11

lua条件判断

关系运算符

说明

<

小于

>

大于

<=

小于等于

>=

大于等于

==

等于

~=

不等于

在使用"=="做等于判断时,要注意对于table,userdata和函数,lua是作引用比较的。也就是说,只有当两个变量引用同一个对象时,才认为他们相等。

代码语言:javascript
复制
listA = {'a','b','c'}
listB = {'a','b','c'}
print(listA==listB) --output false
代码语言:javascript
复制
local a,b,c = nil,2,3  --类似go的多赋值

print(a and b) --output: nil
print(a or b or c)  --output: 2
print(not a) --output true

上面用例and or在C语言会返回0或1,但是lua中a and b如果a为nil,则返回a 否则返回b, a or b中如果a为nil,则返回b否则返回a

代码语言:javascript
复制
function getList(users)
    local temp = ''
    for k,v in  ipairs(users) do
        temp = temp..'\n'..k..'=>'..v
    end
    return 'ok',temp
end

users = {1,2,nil,4,5,6}

msg,temp = getList(users) --output: ok    1=>1 \n 2=>2
print(msg,temp)
代码语言:javascript
复制
function getList(users)
    local temp = ''
    for k,v in  pairs(users) do
        temp = temp..'\n'..k..'=>'..v
    end
    return 'ok',temp
end

users = {1,2,nil,4,5,6}

msg,temp = getList(users) --output: ok    1=>1 2=>2 4=>4 5=>5 6=>6
print(msg,temp)

两段代码看似一样,但其实体现了ipairs和pairs的区别,ipairs遇到nil会终止,而pairs会跳过。 并且此示例程序还演示了多返回值的写法,和go很类似 接收值_可忽略参数 迭代文件中每行io.lines 迭代table pairs 迭代数组ipairs 迭代单词string.gmatch

控制结构

if else elseif for while break

代码语言:javascript
复制
x   = 1
sum = 0
while x<= 5 do
    sum = sum + 1
    x = x + 1
end

print(sum)  --output: 5
代码语言:javascript
复制
for x=0,5,1 do
  while true do
        if x % 2 == 0 then
          break
        end
        print(x)
        x = x + 1
    end
end

--output  1 3 5

lua是没有continue,上面代码变相实现了continue的功能,翻译下for循环可能就是我们常见的 for x=0;x<=5;x++ 操作。循环代码跟do关键字 条件判断为then

类似 do-while 循环

代码语言:javascript
复制
x = 10
repeat
    print(x)
until false

只有until为真才能退出,正好与C相反

函数的例子

代码语言:javascript
复制
foo = {}
foo.bar = function(a,b,c)
    print(a,b,c) --output: 1 2 3
end

foo.bar(1,2,3);

可变长参数

代码语言:javascript
复制
function func(...)
    local temp = {...}
    print(table.concat(temp,',')) --output: 1,2,3,4
end

func(1,2,3,4)
代码语言:javascript
复制
--更简化的循环遍历
myTable = {1,2,3,4,5}
sum = 0
for index = 1,#myTable do
    sum = sum + myTable[index]
end

print(sum)  --output:15
小tips

在参数传递过程中 当函数参数是table类型时,是按引用传递的,其他都是按赋值传递的。这点也和go有类似之处

代码语言:javascript
复制
function func(name,...)
        print(name) --ouput: xiaoming
        print(type(...)) --output: number
        print(select('#',...)) --output: 4 获取长度
        print(select(3,...)) --output: 3 4 从第三个位置开始返回
end

func('xiaoming',1,2,3,4)

lua模块

test.lua

代码语言:javascript
复制
local test = {}

name = 'xiaming'
age = 12 

user = {name=name,age=age}
function getUser()
    return user.name,user.age
end

function test.getList()
        return 'list','list';
end

return test

main.lua

代码语言:javascript
复制
test = require('test')

print(name)  --output: xiaoming 可以直接使用

val1,val2 = getUser() --output: xiaming    12

test.getList() --output: list,list

print(val1,val2)

上面简单示例了两种函数使用方式 getUser 和test.getList,推荐第二种写法,如果相同函数名的话后面会覆盖掉前面的

Lua 元表(Metatable)

_index 源方法

当你通过键来访问 table 的时候,如果这个键没有值,那么Lua就会寻找该table的metatable(假定有metatable)中的__index 键。如果__index包含一个表格,Lua会在表格中查找相应的键。

代码语言:javascript
复制
 other = {key3=10,key4=20}
 mytable = setmetatable({key1=1,key3=3},{__index=other})

 print(mytable.key4) --output: 20

for k,v in pairs(mytable) do
        print(k..'=>'..v)

end
--output : 1 3

同时可以使用函数逻辑处理

代码语言:javascript
复制
 mytable = setmetatable({key1 = "value1"}, {
  __index = function(mytable, key)
    if key == "key2" then
      return "metatablevalue"
    else
      return nil
    end
  end
})

print(mytable.key1,mytable.key2)

__newindex 元方法

__newindex 元方法用来对表更新,__index则用来对表访问 。当你给表的一个缺少的索引赋值,解释器就会查找__newindex 元方法:如果存在则调用这个函数而不进行赋值操作。

代码语言:javascript
复制
mymetatable = {}
mytable = setmetatable({key1 = "value1"}, { __newindex = mymetatable })

print(mytable.key1)

mytable.newkey = "新值2"
print(mytable.newkey,mymetatable.newkey)

mytable.key1 = "新值1"
print(mytable.key1,mymetatable.key1)
代码语言:javascript
复制
mytable = setmetatable({key1 = "value1"}, {
  __newindex = function(mytable, key, value)
        rawset(mytable, key, "\""..value.."\"")

  end
})

为表添加操作符 文档页面: http://www.runoob.com/lua/lua-metatables.html

__tostring 元方法

代码语言:javascript
复制
other = {key3=10,key4=20}
 mytable = setmetatable({key1=1,key3=3},{
 __index=other,
 __tostring = function(mytable)
                return 'todo处理'
              end
 })

print(mytable.key4) --output: 20
print(mytable) --output: todo处理

lua面向对象

lua的对象支持给人的第一感觉不像是以前所认知的面向对象写法,而大部分是table+function的一种组合

代码语言:javascript
复制
obj = {name='lili'}

function obj.getName()
        return obj.name
end
ret = obj.getName()
print(ret) --output: lili
代码语言:javascript
复制
Company = {title='',seo='',content=''}

function Company:new (title,seo,content)
     o = {}  --此处为真正的创建一个新对象
     setmetatable(o, self) 
     self.__index = self  --将self绑定到o这个新对象上
     self.title = title or ''
     self.seo = seo or ''
     self.content = content or ''
     return o  --返回新对象
end

function Company:getInfo()
        return string.format('title-seo-content: %s %s %s',self.title,self.seo,self.content );
end

obj = Company:new(1,2,3)
print(obj.title) --output:  1
ret = obj:getInfo()
print(ret) --output: title-seo-content: 1 2 3

:是lua面向对象的语法糖。Account:new(conf)等同于Account.new(self, conf),相当于将调用者自身当做第一个参数,使用冒号调用就相当于隐式地传递self参数。

参考部分连接整理

菜鸟教程 面向对象解释 Metatable

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-07-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 呆呆熊的技术路 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • lua基础语法
  • Math函数库
  • String函数库
  • 新类型-强大的talbe
    • table函数库
    • 入栈 出栈操作
    • 队列操作
      • 日期时间函数
      • lua条件判断
      • 控制结构
        • 小tips
        • lua模块
        • Lua 元表(Metatable)
        • lua面向对象
        • 参考部分连接整理
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档