物联网学习---番外篇Lua脚本编程扫盲

Posted 玖零大壮

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了物联网学习---番外篇Lua脚本编程扫盲相关的知识,希望对你有一定的参考价值。

在后面的物联网教程中,我们很快就会接触到Lua这个脚本语言,那么本篇内容结合后续的一些需要的开发点,针对Lua零基础的读者写一篇入门扫盲文章。


01

Lua 介 绍


Lua是一个小巧的脚本语言,其目标是成为一个很容易嵌入其它语言中使用的语言。同样的,基于Lua的定位,它并不适合作为开发独立应用程序的语言。


它有以下特性:

  • 轻量级:Lua语言的官方版本只包括一个精简的核心和最基本的库。这使得Lua体积小、启动速度快,从而适合嵌入在别的程序里,5.0.2版的Lua的内核小于120KB。

  • 可扩展:Lua并不象其它许多"大而全"的语言那样,包括很多功能,比如网络通讯、图形界面等。但是Lua提供了非常易于使用的扩展接口和机制:由宿主语言(通常是C或C++)提供这些功能,Lua可以使用它们,就像是本来就内置的功能一样。

  • 其它特性:Lua还具有其它一些特性:同时支持面向过程(procedure-oriented)编程和函数式编程(functional programming);自动内存管理;只提供了一种通用类型的表(table),用它可以实现数组,哈希表,集合,对象;语言内置模式匹配等。

___来源 百度百科


在这里我首先推荐一个可以在线运行Lua的网站,我们接下来的实验都在这个网站上在线运行。

https://www.runoob.com/try/runcode.php?filename=datatype1&type=lua


02

注释 及 函数


Lua的函数是按照下面格式定义的:

function 函数名(参数1, 参数2, ...)    

   函数体 

end


Lua的注释有以下三种:

  • 单行注释:两个减号是单行注释

--

  • 多行注释

--[[  

多行注释  

多行注释  

--]]


运行以下程序:

--测试函数定义function sayHello() print("公众号:玖零大壮") print("print是Lua自带打印函数")end--字符串连接符号演示function fun1(para1) print("两个逗号连接两边的字符串"..para1) print("连接符1" .. "连接符2".. "连接符3")end--多参数传递演示function fun2(para1, para2) print("print中逗号用法") print(para1, para2)endsayHello(); --语句后面可带分号,也可不带fun1("Hello")fun2("数字",1);


【物联网学习---番外篇】Lua脚本编程扫盲

上面额外演示了以下内容:

  • ..用来连接字符串,并且连接符可以与两边的字符串间有空格

  • 语句后面可以有分号,也可以无分号。和Matlab挺像的【物联网学习---番外篇】Lua脚本编程扫盲

  • print()是lua自带的打印输出函数,不同参数之间逗号分隔


03

变 量 修 饰 符


在默认情况下,变量总是认为是全局的,全局变量不需要声明,给一个变量赋值后即创建了这个全局变量。


local是lua特有的关键词,表示声明一个局部变量。

local a = "我是局部变量a"b = "我是全局变量b"function fun1() a = "我是函数内声明的全局变量a" endfunction fun2() local b = "我是函数内局部变量b" end
print(a)print(b)fun1()fun2()print(a)print(b)


【物联网学习---番外篇】Lua脚本编程扫盲

上面演示了全局变量和局部变量的用法,记住local这个关键词修饰符就行了。


访问一个没有初始化的全局变量也不会出错,只不过得到的结果是:nil

如果你想删除一个全局变量,只需要将变量赋值为nil。(nil相当于其它语言的null)

print(a) --因为a没有声明,所以是nila = 1local b = 1print("a+b=" .. a+b)a=nil --给变量赋值为nil就是删除该变量b=nilprint(a,b)

【物联网学习---番外篇】Lua脚本编程扫盲


再看下面的实验

【物联网学习---番外篇】Lua脚本编程扫盲

你看,全局变量就是这么豪横!!


04

数 据 类 型


Lua 是动态类型语言,变量不要类型定义,只需要为变量赋值。值可以存储在变量中,作为参数传递或结果返回。


Lua 中有 8 个基本类型分别为:nil、boolean、number、string、userdata、function、thread 和 table。

【物联网学习---番外篇】Lua脚本编程扫盲

表 lua数据类型概览 来源runoob


来做个实验

print(type(nil)) -- nilprint(type(true)) -- booleanprint(type(10.4*3)) -- numberprint(type("Hello world")) -- stringprint(type(print)) -- functionprint(type(type)) -- functionprint(type(type(X))) -- string


【物联网学习---番外篇】Lua脚本编程扫盲

注意一个有意思的地方:

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


【物联网学习---番外篇】Lua脚本编程扫盲


关于数据类型table,得单独在下面的小章节解释。


05

字 符 串 操 作


字符串或串(String)是由数字、字母、下划线组成的一串字符。


Lua 语言中字符串可以使用以下三种方式来表示:

  • 单引号间的一串字符

  • 双引号间的一串字符

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

string1 = "Hello"--下面有个转义字符print(""字符串 1 是"",string1)
string2 = 'IOT'print("字符串 2 是",string2)
string3 = [[Study]]print("字符串 3 是",string3)

【物联网学习---番外篇】Lua脚本编程扫盲


Lua也自带了一些字符串的操作函数,这里我就介绍我后面的教程中所需要的知识点:字符串格式化和字符串分割。


字符串格式化函数string.format()

【物联网学习---番外篇】Lua脚本编程扫盲


字符串分割:

lua中没有C语言那样直接用来分割的split函数,但是我们可以自定义,下面是我从网上直接找来的代码。

---------------------------------------------------------------- 按照字符分割字符串 ---- @param str 字符串 ---- @param delimiter 分割字符 ---- @return 返回字符串数组 ---- @example local arr = split("123#321","#") ---- print(arr[1])-- print(arr[2])-- 来源:https://www.runoob.com/note/28521--------------------------------------------------------------function split(str,delimiter) local dLen = string.len(delimiter) local newDeli = '' for i=1,dLen,1 do newDeli = newDeli .. "["..string.sub(delimiter,i,i).."]" end
local locaStart,locaEnd = string.find(str,newDeli) local arr = {} local n = 1 while locaStart ~= nil do if locaStart>0 then arr[n] = string.sub(str,1,locaStart-1) n = n + 1 end
str = string.sub(str,locaEnd+1,string.len(str)) locaStart,locaEnd = string.find(str,newDeli) end if str ~= nil then arr[n] = str end return arrend


我们接下来做个实验:

【物联网学习---番外篇】Lua脚本编程扫盲

这里注意一点:

在lua中的“数组”(其实lua没有真正的数组概念)的索引值是从1开始的。


(题外话:我为什么需要上面这个字符串分割的功能呢?因为我在后面使用NB模组传数据的时候,为了节省SIM物联卡的流量,通常透传纯数据)


假如说我们想在lua中赋值一个json格式的字符串,比如下面的格式:

[ { "v":{ "lat": 1.2, "lon": 2.3 },    "i":"location",    "a": 0 }]

我们应该怎么做呢?我们其实可以按照下面的方法进行赋值:

local lat = 1.2local lon = 2.3local name = "location"
local json_str = string.format('[{"v":{"lat":%f,"lon":%f},"i":"%s","a":0}]', lat, lon, name)print("----- 第一种表现形式 -----")print(json_str)
local format_pattern = [[[ { "v":{ "lat": %f, "lon": %f }, "i": "%s", "a": 0 }]]]json_str = string.format(format_pattern, lat, lon, name)print("----- 第二种表现形式 -----")print(json_str)

运行结果:

【物联网学习---番外篇】Lua脚本编程扫盲


这个实验是重点,我后面讲解OneNET TCP透传的时候会用到。


其它的字符串操作函数可以暂时忽略,后面不会用到。


06

流 程 控 制 


关于流程控制循环语句、条件语句这一块的内容,我不讲的很仔细,至少我在后面演示的时候基本不用,有兴趣的可以去这里学习一下:

https://www.runoob.com/lua/lua-loops.htmlhttps://www.runoob.com/lua/lua-decision-making.html

这里简单演示一下使用:

local lat = 1.2
-- if else用法if type(lat) ~= "number" then print("lat数据类型不是number")else print("lat数据类型是number")end
-- 数值for循环for i=1,3,1 do print(i)end
-- 迭代器用法local t = {"hello", "iot"}for i,v in ipairs(t) do print(i,v)end

【物联网学习---番外篇】Lua脚本编程扫盲


07

table 表 


table 是 Lua 的一种数据结构用来帮助我们创建不同的数据类型,如:数组、字典等。


table在Lua中是比较重要的一个知识点,建议去这个连接仔细看一下:

https://www.runoob.com/lua/lua-tables.html

下面我简单的做个实验,体会一下其用法。为了方便调试,我贴一个从网络上找到可以输出table内容的print函数,如下:

-- 输出table表内容-- 来源:https://www.cnblogs.com/leezj/p/4230271.htmlfunction print_r ( t )  local print_r_cache={} local function sub_print_r(t,indent) if (print_r_cache[tostring(t)]) then print(indent.."*"..tostring(t)) else print_r_cache[tostring(t)]=true if (type(t)=="table") then for pos,val in pairs(t) do if (type(val)=="table") then print(indent.."["..pos.."] => "..tostring(t).." {") sub_print_r(val,indent..string.rep(" ",string.len(pos)+8)) print(indent..string.rep(" ",string.len(pos)+6).."}") elseif (type(val)=="string") then print(indent.."["..pos..'] => "'..val..'"') else print(indent.."["..pos.."] => "..tostring(val)) end end else print(indent..tostring(t)) end end end if (type(t)=="table") then print(tostring(t).." {") sub_print_r(t," ") print("}") else sub_print_r(t," ") end print()end

如下测试代码:

local t ={} -- 初始化表t[1] = "Hello" -- 赋值t.h = "IOT"t.a = {"hello", "iot"}print_r(t)t = nil --移除引用,Lua垃圾回收会释放内存

仔细揣摩一下,新增值时,索引的方法。


08

面 向 对 象 


面向对象编程(Object Oriented Programming,OOP)是一种非常流行的计算机编程架构,Lua同样支持面向对象的编程方式,支持继承、多态、抽象。


我们知道,对象由属性和方法组成。Lua中最基本的结构是table,所以需要用table来描述对象的属性。


Lua 中的 function 可以用来表示方法。那么Lua中的类可以通过 table + function 模拟出来。


请看下面的实验:

-- 初始化Area = {width = 0, height=0}-- 方法1function Area:SetPara(width, height) self.width = width; self.height = height;end-- 方法2function Area:Squrare() return self.width * self.height;end
print(Area.width , Area.height)Area:SetPara(10,20)print(Area.width , Area.height)print("面积=" .. Area:Squrare())

看一下这个用法,大致的知道怎么回事儿就行。


讲话了,我写到这里就完事儿了,手打字都打酸了。有了以上这些,足以应对后面的实验了。


点击下方原文链接查看相关文章

以上是关于物联网学习---番外篇Lua脚本编程扫盲的主要内容,如果未能解决你的问题,请参考以下文章

OneNET物联网TCP透传接入及自定义Lua解析脚本

spring boot 学习番外篇:超快速项目初始化

H5学习_番外篇_PHP数据库操作

H5学习_番外篇_PHP数据库操作

大牛讲堂 | 番外篇——Caffe作者贾扬清教你怎样打造更加优秀的深度学习架构

深度学习CPU(番外篇)——初识总线