自学成菜-lua杂记学习法

  • 学习背景: 一直想去体验下openrestry,可惜一直没动力去完成这件事,正好工作原因需要调研,就开启体验之旅吧。开始前需要对lua语法有简单了解和认识
  • 流水式计划:
    • 基础语法简单熟悉
    • openrestry模块知识点实践
    • 一个小项目

lua基础语法

print("hello lua")
复制代码

获取数据类型 函数type

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
复制代码
  以上出现了几个关键词简单描述下:
  1. local相当于声明变量b为局部变量
  2. --为单行注释 --[[ code ]]为多行注释
复制代码
local a = 0

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

if a then
   print('pass')
else
   print('no pass') --output:no pass
end
复制代码

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

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是没有函数提升的概念的,所以需要先声明后使用

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
复制代码
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函数库

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

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函数库

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

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函数库
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
复制代码
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
复制代码
class = {1,2,3,4,5}
max = table.maxn(class);
print(max)   --output: 5
复制代码
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,移除最后一位

入栈 出栈操作

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
复制代码

队列操作

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时间戳

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
复制代码

时间戳转时间

    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是作引用比较的。也就是说,只有当两个变量引用同一个对象时,才认为他们相等。

listA = {'a','b','c'}
listB = {'a','b','c'}
print(listA==listB) --output false
复制代码
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

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)
复制代码
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

ipairs 一般用于需要下标、迭代 array 形式的 table; pairs 可以用来迭代字典形式的 table 。

控制结构

if else elseif for while break

x   = 1
sum = 0
while x<= 5 do
    sum = sum + 1
    x = x + 1
end

print(sum)  --output: 5
复制代码
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 循环

x = 10
repeat
    print(x)
until false
复制代码

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

函数的例子

foo = {}
foo.bar = function(a,b,c)
    print(a,b,c) --output: 1 2 3
end

foo.bar(1,2,3);
复制代码

可变长参数

function func(...)
	local temp = {...}
	print(table.concat(temp,',')) --output: 1,2,3,4
end

func(1,2,3,4)
复制代码
--更简化的循环遍历
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有类似之处

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

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

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会在表格中查找相应的键。

 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
复制代码

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

 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 元方法:如果存在则调用这个函数而不进行赋值操作。

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)
复制代码
mytable = setmetatable({key1 = "value1"}, {
  __newindex = function(mytable, key, value)
        rawset(mytable, key, "\""..value.."\"")

  end
})
复制代码

为表添加操作符 文档页面: www.runoob.com/lua/lua-met…

__tostring 元方法

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的一种组合

obj = {name='lili'}

function obj.getName()
        return obj.name
end
ret = obj.getName()
print(ret) --output: lili
复制代码
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

喜欢lua的朋友可以关注公众号 呆呆熊一点通 一起进步

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值