LUA基础语法
目录
变量篇
算数运算符
条件分支语句与循环语句
函数
表 Table
全局变量与本地变量
协程
元表
面向对象(封装,继承,多态)
常用自带库
垃圾回收
变量篇
print("hello")
print("lua")
--注释
--[[多行注释1
]]--[[多行注释2
]]----[[多行注释3
--]]--变量
a=5
b=nil
print(a)--多重赋值
aa,bb=1,2
aaa,bbb,c=1,2
print(aaa,bbb,c)--多变量赋值
a,b,c= 1,2
print(c)--不够会自动为空,多了会省略 --数值型
q=0x11
print(q)
print(type(q))--string
x="ajn8uah"
y='jkHJUb90'
xx="jbs\nhk"
print(x,y,xx)
yy=x..y--拼接
print(yy)
print(string.format("我今年%d岁",10))print("\n")
tonum=tonumber("10")
tostr=tostring(10)
print(string.upper(y))
print(string.lower(yy))
print(string.reverse(xx))
print(string.find(yy,"HJ"))
print(string.sub(yy,5,9))
print(string.rep(y,4))
print(string.gsub(yy,"j","xxx"))print("\n")
s=string.char(0x45)
s1=string.byte(y,2)
print(#x)
print(tonum,tostr,s,s1)ss=[[w
ky
duohang
shuchu
]]
print(ss)
算数运算符
--算数运算符
-- 有+-*/%
--没有自增自减 ++ --
--没有复合运算符
print (1+2)
a=3
b=4
print(a*b,a/b)
print("154.2"+4)
print("25.2"*5)
print(45%7)
print("幂运算"..2^5)--条件运算符
-- > < >= <= == ~=
print(3>1)
print(2>8)
print(2~=7)
print(7==7)
print("\n")--逻辑运算符,满足短路(第一个是假的则就是假)
-- && ||
-- and or
print(true or false)
print(true and false)
print(false and print(555))
print(not true)
--LUA不支持位运算符,不支持三目运算符--and or
--逻辑与逻辑或
--不仅可以连接bool类型,任何类型都可以连接
--在lua中只有nil与false为假
print(1 and 2)
print(false and 2)print(false or 3)
print(4 or 77)
print(nil or false)x=5
y=1
local res=(x>y)and x or y
print(res)
条件分支语句与循环语句
--条件分支语句if 1>10 thenprint("1>10")
elseprint("no")
endif 8>10 thenprint("8>10")
elseif 8<10 thenprint("8<10")
end--循环语句
--for
--11111
for i=10,15 doprint(i)
end--22222
for i=1,10,2 doprint(i)
end--while
local n=10
while n>1 don=n-1print(n)
end--do while
num=0
repeatprint(num)num=num+1
until num>5 --结束条件
函数
--functionfunction function_name( ... )-- body
enda=function()
end--无参数无返回
function F1()print("F1")
end
F1()F2=function ( )-- bodyprint("F2")
end
F2()--有参数无返回
function F3(a)print(a)
end
F3("1")--可以穿任意参数
F3(1,8,5)--不会报错,自动丢弃--有返回
function F4(a)return a,"444",false
end
temp=F4("4587")
print(temp)
--多返回值时前面申明多个变量来接取
t1,t2,t3=F4(9)
print(t1,t2,t3)--函数的类型
print(type(F4))--函数的重载
--LUA中不支持函数重载,默认调用最后一个申明的函数--变长参数
function F7( ... )--变长参数使用 用一个表存起来 再用arg={...}for i=1,#arg doprint(arg[i])end
endF7(1,5,"444",8,7,true)--函数的嵌套
function F8( ... )F9=function ()print("nyx")endreturn F9
endtt=F8()
F9()--LUA中闭包考点:
function FF( x )--改变了传入参数的生命周期return function ( y )return x+yend
endF10=FF(10)
print(F10(5))--函数多返回值
function test( )-- bodyreturn 11,34,25,3
enda,b,c=test()
print(a)
print(b)
print(c)
表 Table
--表table,所有复杂类型都是表!!!!--数组
a={1,5,222,"nujs",true,8787,nil}
--索引从1开始
print(a[5])
--#是通用的获取长度的关键字
print(#a)
b={45,"sjb",nil,4}
print(#b) --高版本中不会因为中间存在nil而是表的长度被截断--二维数组
aa={{5,7,55},{5,"775",1}}
print(aa[1][3])--数组的遍历
--一维
for i=1,#a doprint(a[i])
endfor i=1,#b doprint(b[i])
end
--二维
for i=1,#aa dob=aa[i]for j=1,#b doprint(b[j])end
end--自定义索引
bb={[0]="n",2,3,[-1]=4,5}
print(bb[0])
print(#bb)--为:2 3 5
print(bb[-1])c={[1]=1,[2]=2,[6]=7,[11]=9}--比较特别的,注意!
print(#c)--字典
--字典的申明
a={["name"]="nyx",["age"]=18,["1"]=5}
print(a["name"])
print(a["age"])
print(a["1"])
--可以用类似.成员变量的形式得到值
print(a.name)
--但是数字不可以.
--print(a.1)
--修改
a["name"]="wwww"
print(a.name)
--新增
a["sex"]="female"
print(a.sex)
--删除
a["sex"]=nil
print(a.sex)
print("遍历")--模拟字典遍历只能用pairs
for i,k in pairs(a) doprint(i.."_"..k)
end
--类和结构体
--lua中默认没有面向对象,需要自己实现
--封装 成员变量,成员函数。。。。。。
Student={age=11,sex=true,set=4,Up=function (age)--这个age与上面的不是同一个,是一个全局变量,除非写Student.ageprint(age.age)print("vgjvv")end,Learn=function ()-- bodyprint("哈哈哈哈")end
}
--申明表过后,在表外去申明表有的变量和方法
Student.name="tls"
Student.Speak=function ()print("speak")
endprint(Student.set)
Student.Up(Student)
Student.Learn()--lua中.与:的区别
Student.Speak()
--:时会默认把第一个参数传入方法中
Student:Up()--函数的第三种声明方式
function Student:Speak2()--lua中 有一个关键字 self 表示,默认传入的第一个参数print(self.name.."11shuohua")
endStudent:Speak2()--表的公共操作
t1={{age=1,name="nnn"},{age=77,name="www"}}
t2={name="thd",sex=true}--插入
print(#t1)
table.insert(t1,t2);
print(#t1)
print(t1[1])
print(t1[2])
print(t1[3])
print(t1[1].name)--删除
--remove 传表,会移除最后一个内容
table.remove(t1)
print(#t1)
print(t1[1].name)
--remove 传两个参数,第一个是表,第二个是索引
table.remove(t1,2)
print(#t1)t2={5,8,nil,22,"bbb",4}
print(#t2.."--t2")--排序
t3={5,8,42,22,1,4}
table.sort(t3)
for i,v in pairs(t3) doprint(v)
end
--逆序
table.sort( t3, function(a,b)if a>b thenreturn trueend
end)
for _,v in pairs(t3) doprint(v)
end--拼接
tb={"155","87","h","888745",5544}
str=table.concat(tb,"。")--返回的是字符串,对表中元素有要求
print(str)
--迭代器
--主要是用来遍历表的
a={[0]=1,2,[-1]=5,nil,"444",8}--ipairs,从1开始遍历
for i,k in ipairs(a) doprint("键值对"..i.."_"..k)
endprint("\n")
--pairs遍历,可以找到所有的键的值
for i,v in pairs(a) doprint("键值对"..i.."_"..v)
end
全局变量与本地变量
--全局变量与本地变量
--全局变量
a=1
b="124"--局部变量
for i=1,2 dolocal c="xx"
end
print(c)
--多脚本执行
--关键字 require("脚本名")或者单引号‘’
require("test")
print(testa)
print(aa)--脚本卸载
require("test")--加载一次后不会再执行
--package.loaded["脚本名"],为true说明已经被执行过
print(package.loaded["test"])
--卸载已经执行过的脚本
package.loaded["test"]=nil
print(package.loaded['test'])
local ra=require('test')--可以接收return出去的本地变量
print(ra)--大G表
--_G(是一个特殊的table,保存所有的全局变量)
for k,v in pairs(_G) do--print(k,v)
end
协程
-----------------------------协程(协同程序)---------------------------
----------------------创建(create创建与function函数创建)--------------------
--coroutine.create()
fun=function ( )-- bodyprint(13)
end
co=coroutine.create(fun)
--协程的本质是一个线程对象
print(co)
print(type(co))--函数创建,返回为函数
co2=coroutine.wrap(fun)
print(co2)
print(type(co2))----------------------------------运行--------------------------
--create创建方式的运行
coroutine.resume(co)--函数创建方式运行
co2()----------------------------------------挂起-------------------------fun2=function()local i=1while true doprint(i)i=i+1print(coroutine.status(co3))--协程挂起函数coroutine.yield()--其中可以带返回值coroutine.yield(i),协程的第一个返回值是返回有没有执行成功--coroutine.yield(i)end
endco3=coroutine.create(fun2)
isT,tempi=coroutine.resume(co3)
print(isT,tempi)
coroutine.resume(co3)--在lua中因为程序是从上到下执行一次 ,所有只有重启一次他才会继续执行
coroutine.resume(co3)
coroutine.resume(co3)co4=coroutine.wrap(fun2)
--此方式的协程调用也可以有返回值,但是没用默认的第一个返回值
co4()
co4()
co4()
co4()--与上面相同,执行一次-----------------------------------状态------------------------------------------
--coroutine.statusd(协程对象)
--dead 结束
--suspended 暂停
--running 进行中
print(coroutine.status(co3))
print(coroutine.status(co))
--得到现在正在运行的协程编号(线程号)
print(coroutine.running())
元表
--------------------元表---------------------
--------------------元表的概念---------------------
--任何表变量都可以作为另一个表变量的元表
--任何变量都可以有自己的元表
--当对有元表的表执行操作时,会执行元表中的内容
--------------------设置元表---------------------
t1={}
myt={}
--设置元表函数
setmetatable(myt,t1)--将第一个参数设置成第二个元表--------------------元表的操作---------------------
-----------------—__tostring
t2={__tostring=function(i)return i.nameend
}
myt1={name="nyx"
}setmetatable(myt1,t2)--将第一个参数设置成第二个元表
print(myt1)--------------------------__call:当第一个参数被当作一个函数来使用时,会默认调用__call中的内容
--当希望穿参数时,一定要默认第一个参数是调用者自己
t3={__tostring=function(i)return i.nameend,__call=function(a,b)print(a)print(b)print("love")end
}
myt2={name="nyx"
}setmetatable(myt2,t3)--将第一个参数设置成第二个元表
print(myt2)
--把子表当作函数使用,就会调用元表的__call方法
myt2(5)-------------------------------------运算符重载
meta={--相当于运算符重载,当子表使用+运算符时,会调用方法__add=function(t1,t2)return tt.age+tt1.ageend,__sub=function(t1,t2)return tt.age-tt1.ageend,__mul=function(t1,t2)return tt.age*tt1.ageend,__div=function(t1,t2)return tt.age/tt1.ageend,__mod=function(t1,t2)return tt.age%tt1.ageend,__pow=function(t1,t2)return tt.age^tt1.ageend,__eq=function(t1,t2)return tt.age==tt1.ageend,__lt=function(t1,t2)return tt.age<tt1.ageend,__le=function(t1,t2)return tt.age<=tt1.ageend,
--lua中没有不等于与大于,大于等于__concat=function(t1,t2)return "t1..t2"end}
tt={age=1}
setmetatable(tt,meta)
tt1={age=2}print(tt..tt1)----------------------__index与__newindex-------------------------mm={age=2
}
--将__index的赋值写在表外进行初始化
mm.__index=mm
ty={}
setmetatable(ty,mm)print(getmetatable(ty))--得到元表的方法
--__index当子表中ty找不到某个属性时,会到元表中__index指定的表去找索引
print(ty.age)--————index查找可以层层向上
mmFa={sx=5
}
mmFa.__index=mmFa
setmetatable(mm,mmFa)
print(mm.sx)--__newIndex 当赋值时,如果赋值一个不存在的索引,那么会把这个值附到newIndex所指的表中,不会修改自己
ma={}
ma.__newIndex={}
mt={}
setmetatable(mt,ma)
mt.grade=99
print(mt.grade)
print(ma.__newIndex.grade)
面向对象(封装,继承,多态)
-----------------------------面向对象--------------------------
-----------------------------封装--------------------
--面向对象,类,其实都是基于table来实现Object={}
Object.id=1
function Object:Test()print(self.id)end--冒号 会将自动调用这个函数的对象,作为第一个参数传入的写法
function Object:new( )-- self代表我们默认传入的第一个参数--对象就是变量,返回一个新的变量,返回出去的内容,本质上就是表对象local obj={}--元表知识,__index 当找自己的变量找不到时,就会去找元表当中__index指向的内容self.__index=selfsetmetatable(obj,self)return obj
end
local myObj=Object:new()
print(myObj)
print(myObj.id)
myObj:Test()
--想当于对空表中,申明一个新的属性叫id
myObj.id=2
print(Object.id)
myObj:Test()------------------------------------继承---------------------
--写一个用于继承的方法
function Object:subClass(classname)--_G知识点,是总表,所有声明的全局变量都以键值对的形式存在其中_G[classname]={}--写相关继承规则local obj=_G[classname]self.__index=self--子类 定义一个base属性 base属性代表父类obj.base=selfsetmetatable(obj,self)
end
print(_G)
_G["a"]=1
print(a)Object:subClass("Person")
local p1=Person:new()print(p1.id)------------------------------------多态-------------------------
print("------------------------------------------")
--相同行为不同表现
--相同方法,不同执行逻辑,就是多态
Object:subClass("GameObject")
GameObject.posX=0
GameObject.posY=0
function GameObject:Move()self.posX=self.posX+1self.posY=self.posY+1print(self.posX)print(self.posY)
endGameObject:subClass("Player")
function Player:Move()-- base.Move构建一个base保留父类的方法--这里的base指的是Gameobject类,此方式调用相当于将基类表作为第一个参数传入方法--避免将基类表传入到方法中,这样相当于公用一张表的属性--我们如果要执行父类逻辑,我们不要直接冒号调用--要通过.调用然后传入第一个参数self.base.Move(self)
end
local P1=Player:new()
P1:Move()
--目前这种写法,不同对象使用的成员变量居然是相同的
local P2=Player:new()
P2:Move()
常用自带库
-------------------lua的自带库----------------------------------------时间---------------------
--系统时间
print(os.time())
--自己传入参数得到时间
print(os.time({year=2024,month=12,day=29}))--利用os.date("*t")
local nowtime = os.date("*t")
print(nowtime)
for i,v in pairs(nowtime) doprint(i,v)
end
print(nowtime.hour)
-------------------数学运算---------------------
--math
--绝对值
print(math.abs(-23))
--弧度转角度
print(math.deg(math.pi))
--三角函数,传弧度
print(math.cos(math.pi))
--向下向上取整
print(math.floor(2.6))
print(math.ceil(5.2))--最大值与最小值
print(math.max(1,4))
print(math.min(4,1))--小数分为整数与小数俩部分
print(math.modf(2.4))--幂运算
print(math.pow(2,5))--随机数,先设置随机数种子
math.randomseed(os.time())
print(math.random(100))
print(math.random(100))--开方
print(math.sqrt(9))-------------------路径---------------------
--lua脚本加载路径
print(package.path)
垃圾回收
------------------------垃圾回收--------------------
--关键字 collectgarbage
--获取当前lua占用内存数 K字节,用返回值*1024得到具体内存占用字节数
collectgarbage("count")test={id=1,name="222222"}
print(collectgarbage("count"))--lua中的机制与C#中的机制很类似,解除羁绊则变为垃圾
test=nil--进行垃圾回收,看类似于GC
collectgarbage("collect")
print(collectgarbage("count"))
--lua中其实有自动定时垃圾回收
--但是在Unity热更新开发中尽量不要用自动垃圾回收
相关文章:
LUA基础语法
目录 变量篇 算数运算符 条件分支语句与循环语句 函数 表 Table 全局变量与本地变量 协程 元表 面向对象(封装,继承,多态) 常用自带库 垃圾回收 变量篇 print("hello") print("lua") --注释 --[[…...
SpringBoot的pom.xml文件中,scope标签有几种配置?
1.compile(默认) 含义:表示该依赖在项目的所有阶段(编译、测试、运行)都需要。 当你依赖一个库,并且这个库是你项目的核心部分,比如 Spring Boot 的spring - boot - starter - web,…...
Leetcode729: 我的日程安排表 I
题目描述: 实现一个 MyCalendar 类来存放你的日程安排。如果要添加的日程安排不会造成 重复预订 ,则可以存储这个新的日程安排。 当两个日程安排有一些时间上的交叉时(例如两个日程安排都在同一时间内),就会产生 重复…...
青少年编程与数学 02-006 前端开发框架VUE 02课题、创建工程
青少年编程与数学 02-006 前端开发框架VUE 02课题、创建工程 一、开发环境(一)WebStorm安装WebStorm配置WebStorm安装中文语言包安装 Translation插件 (二)Node.jsWindows系统安装Node.jsLinux系统安装Node.jsNode.js与Vue.js的关…...
Redis的生态系统和社区支持
Redis的生态系统和社区支持 1. Redis 生态系统 1.1 Redis核心 Redis 是一个高性能的内存存储系统,支持丰富的数据结构(如字符串、列表、集合、哈希和有序集合)。它的核心提供了: 高性能数据存储:单线程模型支持每秒数百万级别的操作。多种数据结构:适用于多样化场景,如…...
Tomcat解析
架构图 核心功能 Tomcat是Apache开源的轻量级Java ServletServlet容器,其中一个Server(Tomcat实例)可以管理多个Service(服务),一个Service包含多个Connector和一个Engine,负责管理请求到应用的…...
UML之组合与聚合
关联和链接关系在很多情况下是对称的,即被关联的两个类都有以自己为源端对方为目标端的角色存在,而且角色与源端类的属性是等价的,即在关联一端的关联端(角色)等价于另外一端的属性。例如,在下图中…...
数据结构理论篇(期末突击)
找往期文章包括但不限于本期文章中不懂的知识点: 个人主页:我要学编程(ಥ_ಥ)-CSDN博客 所属专栏: 学校课程突击 下面均是为了应付学校考试所用,如果有涉及部分知识点下面未说明,可以去我的数据结构专栏看看或者自行在…...
《一文读懂PyTorch核心模块:开启深度学习之旅》
《一文读懂PyTorch核心模块:开启深度学习之旅》 一、PyTorch 入门:深度学习的得力助手二、核心模块概览:构建深度学习大厦的基石三、torch:基础功能担当(一)张量操作:多维数组的神奇变换(二)自动微分:梯度求解的幕后英雄(三)设备管理:CPU 与 GPU 的高效调度四、to…...
摆脱Zotero存储限制:WebDAV结合内网穿透打造个人文献管理云平台
文章目录 前言一、Zotero安装教程二、群晖NAS WebDAV设置三、Zotero设置四、使用公网地址同步Zotero文献库五、使用永久固定公网地址同步Zotero文献库 前言 如果你是科研工作者、学生或者任何需要频繁处理大量学术资料的人士,你一定对如何高效管理和引用文献感到头…...
Flutter封装一个三方ViewPager学习
Flutter如何实现一个增强的 PageView,支持自定义页面切换动画。 前置知识点学习 CrossAxisAlignment CrossAxisAlignment 是 Flutter 中用于控制布局子组件在交叉轴(cross axis)方向上的对齐方式的一个枚举类。它主要在 Flex 布局模型中使…...
服务器数据恢复—离线盘数超过热备盘数导致raidz阵列崩溃的数据恢复
服务器数据恢复环境&故障: 一台配有32块硬盘的服务器在运行过程中突然崩溃不可用。经过初步检测,基本上确定服务器硬件不存在物理故障。管理员重启服务器后问题依旧。需要恢复该服务器中的数据。 服务器数据恢复环境: 1、将服务器中硬盘…...
nginx-nginx的缓存集成
缓存的概念 缓存就是数据交换的缓冲区,被称作cache,访用户想要获取数据时,就会先从缓存中去查询数据,如果缓存中有就会直接返回给用户,若果缓存中没有,则会发出请求从服务器中重新查询数据,将数…...
【Vim Masterclass 笔记01】Section 1:Course Overview + Section 2:Vim Quickstart
文章目录 Section 1:Course Introduction 课程概述S01L01 Course Overview 课程简介课程概要 S01L02 Course Download 课程资源下载S01L03 What Vim Is and Why You Should Learn It 何为 Vim?学来干啥?1 何为 Vim2 为何学 Vim Section 2&…...
【数据库系列】Spring Boot 中使用 MyBatis 详细指南
一、基础介绍 1.1 MyBatis MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 P…...
Azure Airflow 中配置错误可能会使整个集群受到攻击
网络安全研究人员在 Microsoft 的 Azure 数据工厂 Apache Airflow 中发现了三个安全漏洞,如果成功利用这些漏洞,攻击者可能会获得执行各种隐蔽操作的能力,包括数据泄露和恶意软件部署。 “利用这些漏洞可能允许攻击者以影子管理员的身份获得…...
Python跨年烟花
目录 系列文章 写在前面 技术需求 完整代码 下载代码 代码分析 1. 程序初始化与显示设置 2. 烟花类 (Firework) 3. 粒子类 (Particle) 4. 痕迹类 (Trail) 5. 烟花更新与显示 6. 主函数 (fire) 7. 游戏循环 8. 总结 注意事项 写在后面 系列文章 序号直达链接爱…...
【代码】Python|Windows 批量尝试密码去打开加密的 Word 文档(docx和doc)
文章目录 前言完整代码Githubdocxdoc 代码解释1. msoffcrypto 方法(用于解密 .docx 文件)read_secret_word_file 函数密码生成与解密尝试try_decrypt_file 函数 2. comtypes 方法(用于解密 .doc 文件)read_secret_word_file 函数注…...
java开发中注解汇总
注解作用位置注意mybatis Data Getter Setter ToString EqualsAndHashCode AllArgsConstructor NoArgsConstructor Data 代替:无参构造,get,set,toString,hashCode,equals Getter Setter 可放在类和方法上&…...
C# 设计模式(结构型模式):外观模式
C# 设计模式(结构型模式):外观模式 (Facade Pattern) 在复杂系统中,往往会涉及到多个子系统、模块和类。这些子系统的接口和功能可能会让使用者感到困惑和复杂。在这种情况下,我们可以使用外观模式(Facade…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?
在建筑行业,项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升,传统的管理模式已经难以满足现代工程的需求。过去,许多企业依赖手工记录、口头沟通和分散的信息管理,导致效率低下、成本失控、风险频发。例如&#…...
使用van-uploader 的UI组件,结合vue2如何实现图片上传组件的封装
以下是基于 vant-ui(适配 Vue2 版本 )实现截图中照片上传预览、删除功能,并封装成可复用组件的完整代码,包含样式和逻辑实现,可直接在 Vue2 项目中使用: 1. 封装的图片上传组件 ImageUploader.vue <te…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
【学习笔记】深入理解Java虚拟机学习笔记——第4章 虚拟机性能监控,故障处理工具
第2章 虚拟机性能监控,故障处理工具 4.1 概述 略 4.2 基础故障处理工具 4.2.1 jps:虚拟机进程状况工具 命令:jps [options] [hostid] 功能:本地虚拟机进程显示进程ID(与ps相同),可同时显示主类&#x…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
Modbus RTU与Modbus TCP详解指南
目录 1. Modbus协议基础 1.1 什么是Modbus? 1.2 Modbus协议历史 1.3 Modbus协议族 1.4 Modbus通信模型 🎭 主从架构 🔄 请求响应模式 2. Modbus RTU详解 2.1 RTU是什么? 2.2 RTU物理层 🔌 连接方式 ⚡ 通信参数 2.3 RTU数据帧格式 📦 帧结构详解 🔍…...
spring Security对RBAC及其ABAC的支持使用
RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型,它将权限分配给角色,再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...
