自由学习记录(25)
只要有修改,子表就不用元表的参数了,用自己的参数(只不过和元表里的那个同名)
子表用__index“继承”了父表的值,此时子表仍然是空表
一定是创建这样一个同名的变量在原本空空的子表里,
传参要传具体的变量


__index
这样会报错
local obj = {}
x=1
setmetatable(obj, { __index = x})
print(obj.health)

Lua 对于 __index 元方法有严格要求,它必须是一个表或一个函数。
local obj = {}
setmetatable(obj, { __index = 42 }) -- 错误:尝试访问时 Lua 会报错print(obj.health) -- 报错:bad argument #2 to 'setmetatable' (index must be table or function)
在 Lua 中,当 __index 被设置为 nil 时,Lua 的行为是将其视为没有定义 __index 元方法。这不会引发错误,而是简单地返回 nil
Lua 不强制要求 __index 必须被定义或赋值,只在查找键失败时才会检查是否存在有效的 __index
local obj = {}
setmetatable(obj, { __index = nil })print(obj.health) -- 输出: nil
当 Lua 查找一个表中不存在的键时:
- 如果该表的元表中定义了
__index:- 如果
__index是表,Lua 会在这个表中继续查找键。 - 如果
__index是函数,Lua 会调用该函数,并将原表和键作为参数传递(重点在先找到,再传入参数,而且这时候的参数的self什么的也是自己此时传入的参数)
- 如果
- 如果该表的元表存在,但
__index为nil或未定义或者有但是里面没找到,Lua 会直接返回nil,不会报错。

__index 的函数可以没有返回值
Lua 将该返回空的值也视为 nil
__index 的函数在被调用时,会自动接受两个参数(调用的表,缺失的键)
这两个参数是自动传入的,并且在实现 __index 时是强制要求的,不提供这两个参数会导致错误
local obj = {}
setmetatable(obj, {__index = function(table, key)print("Table is:", table)print("Key is:", key)return "Default value" -- 显式返回一个值end
})print(obj.health) -- 输出:
-- Table is: <table: 0x...>
-- Key is: health
-- Default value
setmetatable()
通过特殊的元方法来改变表的行为(延伸),实现默认的操作逻辑,比如算术运算、比较、索引、函数调用等。Lua 会在对应的情况下自动调用它们。
以下是元表里常用的内容:
索引相关
__index:自定义键的访问行为
__index接受的是一个访问对象,可以是表可以是函数,但不可以是单个的变量
当访问表中不存在的键时,Lua 会去元表里的 __index 方法找值,表里有值就拿表,有方法可以返回值就接收这个返回值
示例 1:使用表提供默认值
local defaults = { health = 100, mana = 50 }
local t = {}
setmetatable(t, { __index = defaults })print(t.health) -- 输出: 100(默认值)
print(t.attack) -- 输出: nil(没有定义)
示例 2:使用函数动态生成值
local t = {}
setmetatable(t, {__index = function(_, key)return "键 " .. key .. " 不存在"end
})print(t.unknown) -- 输出: 键 unknown 不存在
__newindex:自定义键的赋值行为
当试图给表中不存在的键赋值时,Lua 会调用 __newindex 方法。
- 可以拦截并自定义赋值逻辑。
示例:限制某些键的赋值
local t = {}
setmetatable(t, {__newindex = function(_, key, value)print("你不能直接添加新键 " .. key .. ",但我记录下来了!")end
})t.newKey = 123 -- 输出: 你不能直接添加新键 newKey,但我记录下来了!
print(t.newKey) -- 输出: nil
算术操作
元表可以通过定义算术相关的元方法,改变表在算术操作中的行为。以下是常用的元方法:
__add:加法
定义两个表相加时的行为:
local t1 = { value = 5 }
local t2 = { value = 10 }setmetatable(t1, {__add = function(a, b)return { value = a.value + b.value }end
})local result = t1 + t2
print(result.value) -- 输出: 15
__sub、__mul、__div、__mod、__pow
这些方法分别用于减法、乘法、除法、取模、幂运算。例如:
local t1 = { value = 2 }
local t2 = { value = 3 }setmetatable(t1, {__mul = function(a, b)return { value = a.value * b.value }end
})local result = t1 * t2
print(result.value) -- 输出: 6
比较操作
元表还可以控制比较操作的行为:
__eq:等于
local t1 = { id = 1 }
local t2 = { id = 1 }setmetatable(t1, {__eq = function(a, b)return a.id == b.idend
})print(t1 == t2) -- 输出: true
__lt 和 __le:小于和小于等于
local t1 = { value = 5 }
local t2 = { value = 10 }setmetatable(t1, {__lt = function(a, b)return a.value < b.valueend
})print(t1 < t2) -- 输出: true
表的行为
__tostring:自定义表的字符串表示
用于定义表被转换为字符串时的行为,例如 print:
local t = { name = "test" }setmetatable(t, {__tostring = function(table)return "表的名字是:" .. table.nameend
})print(t) -- 输出: 表的名字是:test
__len:自定义表的长度
控制 # 操作符的行为:
local t = { a = 1, b = 2 }setmetatable(t, {__len = function()return 100end
})print(#t) -- 输出: 100
__call:使表可以被调用
让表像函数一样调用:
local t = {}setmetatable(t, {__call = function(_, a, b)return a + bend
})print(t(3, 5)) -- 输出: 8
实际使用场景
元表的功能非常强大,常见的使用场景包括:
- 默认值表:使用
__index为表提供默认值。 - 运算符重载:让自定义类型支持算术或比较运算。
- 面向对象编程:通过
__index和元表实现类与对象。 - 只读表:使用
__newindex拦截赋值行为,防止表被修改。 - 代理表:通过
__index或__call动态生成数据。
修正语法思路

关于元表绑定父表的一个小细节
local base = {name = "base",speak = function(self)print("Name is " .. self.name)end
}local derived = {}
setmetatable(derived, { __index = base })-- 调用方法
derived:speak() -- 输出: Name is nil
解释:
derived没有name属性,speak是从元表base中继承的。self绑定到调用者derived,所以self.name为nil。
如果在 derived 中添加属性,行为会改变:
derived.name = "derived"
derived:speak() -- 输出: Name is derived
当使用 : 调用方法时,Lua 会自动将表作为第一个参数传入函数,并绑定到变量 self
self 完全取决于调用者传入的第一个参数
同一个函数,被别的表继承之后,:如果要执行这个函数,self指的就是那个新的继承的表对象
这个self是动态的

这里看上去是在给Object这个表对象写新方法,但这个表对象会被作为元表去被别的表继承,
function这个东西写哪都一样,只是一种简写,对于{}调用自己的方法,然后会有一个self指代自己(这个自己不是真的要是自己,而是使用这个方法时的自己,self的功能重点不在是定义在谁的{},而在对表之间的“继承”关系的强调)

现在再看这个继承的代码看着简单,但是通用性很强,里面的确有很多知识点
把Object声明在全局,突出class的感觉
new和subClass方法也写成全局的
不用:语法糖实现Object万物之父
所有的方法都要传入参数,这个参数不会
参数能不能传入,只靠local对参数的规定
-- Object 万物之父类
local Object = {}-- 创建新对象方法
function Object.new(self)local instance = {}setmetatable(instance, { __index = self }) -- 设置元表,继承父类的方法return instance
end-- 添加一个通用的方法
function Object.say(self, message)print("[" .. tostring(self) .. "] says: " .. message)
end-- 返回 Object 类
return Object
要实现一个万物之父的Object,
首先创建这个大表{},因为是万物之父,所以这个表里包含了new一个新的自己的能力
在这体现为function Object:new()
.....
end
封装
然后是对这个自我实例化的函数的实现,也就是给这个万物之父Object表{}对象,写一个可以创建出新的独立的{}表的方法(这个创建的新{}对象,里面还要实现和Object{}对象里一模一样的功能)
那问题就来到了这个新{}对象的创建,以及这个新{}要怎么复制Object对象里的各种方法和数据
这里巧妙的运用了闭包,即Object{}对象里的new方法,里面存在的各种变量,也是有生命周期的
这一点同c#
所以在这个Object{}对象里的new函数里
local obj={}
...
return obj
这个return的值在外部用变量接了就可以用了
二次强调,这个new的方法是属于Object这个{}的
lua创建一个对象的流程:先写好一个实实在在的{},然后想有新的“实例”,就通过元表setmetatable()把新的“实例”去引用上已经存在的{}里的各种...,这个部分是__index在发挥作用
换句话说,这个功能本是setmetatable()设置元表的一个小分支,
但意外的是这个小分支是实现面向对象的继承和创建新对象的关键
setmetatable()先写元表再写上面的self.__index=self

Lua热更新
Lua 是 Unity 热更新的一种常见选择,但并不是唯一的方案。
以下是详细的解释和 Lua 在 Unity 热更新中的应用场景:
Lua 热更新的核心原理
热更新的目标是在不重新发布客户端版本的情况下更新游戏逻辑。Lua 作为脚本语言,可以加载和运行外部脚本文件,更新逻辑时只需替换脚本资源,而无需重新打包整个应用。
在 Unity 中,Lua 热更新通常通过以下方式实现:
- 将核心逻辑(如主角行为、UI 逻辑)写在 Lua 脚本中。
- 在 C# 程序中嵌入 Lua 虚拟机(通常使用 LuaBridge、SLua 或 XLua 等工具)。
- 在运行时动态加载和执行 Lua 脚本文件,达到热更新的效果。
为什么 Lua 是热门选择
- 游戏行业传统:Lua 广泛应用于 Cocos2d、Corona、Roblox 等游戏引擎,因此在游戏行业中积累了丰富的生态和成熟的实践经验。
- Unity 插件支持:Unity 中有多个成熟的 Lua 框架(如 XLua、SLua、ToLua),可以快速上手,降低实现热更新的技术门槛。
- 适配热更新需求:Lua 支持动态加载脚本,结合 Unity 的 AssetBundle 等机制,可以在运行时替换特定逻辑,满足热更新需求。
热更新的其他方案(非 Lua)
-
ILRuntime(C# 热更新):
- ILRuntime 是一个开源的 .NET 运行时框架,可以让游戏逻辑以 C# 写成的 DLL 文件形式热更新。
- 优点:无需学习新的语言,直接使用 C# 编写代码;性能接近原生逻辑。
- 缺点:复杂度较高,调试和配置成本稍高于 Lua。
-
HybridCLR:
- Unity 原生不支持代码热更新,但使用 HybridCLR(开源的 AOT+Interpreter 混合运行时),可以实现类似 Lua 的热更新效果。
- 优点:完全基于 C#,不需要引入额外语言;性能优越。
- 缺点:配置复杂,需要对 Unity 和 CLR 有深入理解。
-
AssetBundle 热更新:
- 通过资源的动态加载更新 UI、关卡、角色等内容,而不是直接更新逻辑。
- 优点:简单易用,适合仅更新资源的场景。
- 缺点:无法更新游戏逻辑。
-
Python 或其他脚本语言:
- 某些项目可能会选择 Python 或其他轻量脚本语言(如 JavaScript)作为热更新脚本语言,但使用较少,生态不如 Lua 完善。
如果更倾向于使用 C# 完成所有开发任务,也可以探索 ILRuntime 或 HybridCLR 等更贴近 Unity 原生的热更新方案。
Lua的实现流程
eg:活动与任务系统
-
实际场景:
游戏中的限时活动、节日任务等需要随时调整或增加,比如:-
在春节期间增加一个“新年集福活动”。
-
在万圣节期间添加“收集南瓜”的任务,完成后奖励独特皮肤。
-
-
为何需要热更新:
这些任务的规则(比如“收集多少南瓜”、“奖励什么物品”)可能需要动态调整。如果每次都通过重新发布客户端更新,这会导致玩家需要频繁下载新版本,影响体验。 -
热更新解决方案:
开发者只需通过服务器发送新的 Lua 脚本,定义任务逻辑,客户端运行时加载这些脚本即可完成更新。
如果开发者对游戏代码进行了加密或封装,玩家无法随意加载和替换脚本内容。否则,恶意脚本可能造成数据泄露或作弊行为
游戏需要内置一个脚本虚拟机(比如 Lua VM),支持动态加载和执行外部脚本。如果没有这种机制,热更新就无法通过脚本实现。
热更新的限制
游戏逻辑中哪些部分允许用 Lua 控制,哪些是固定在 C# 或引擎层(Unity 原生)中,通常是预先定义好的。
一些核心机制(如图形渲染、网络通信)往往不会交给 Lua 脚本,而是保留在底层代码中。
游戏服务器通常会校验客户端发来的逻辑更新(如活动配置、技能参数)。如果玩家任意替换脚本但未通过服务器校验,可能无法生效。
策划使用Lua
程序员需要预先用框架(如 Unity 的 XLua、ToLua 或自研绑定系统)把 Lua 与游戏的核心逻辑或数据结构连接起来,让 Lua 脚本中的变量和程序代码的数据能够互相访问。以下是常见的绑定机制:
通过 Lua 表映射游戏数据
程序员定义一个数据表(如角色属性、任务数据),并通过接口将其暴露给 Lua 脚本。例如:
public class Player
{public int health = 100;public int mana = 50;
}

策划如何知道哪些变量可以用?
程序员一般要提供一份脚本文档或模板,列出策划可以操作的变量、数据结构和接口。
- 文档需要详细说明:
player.health表示角色当前血量,类型是整数;enemy.attackPower表示敌人的攻击力。- ...
程序员和策划需要约定数据和逻辑的名称
-- Lua 脚本
local tasks = {{ id = 1, name = "收集苹果", required = 10, reward = 100 },{ id = 2, name = "击败敌人", required = 5, reward = 200 }
}
public void LoadTaskData(LuaTable tasks)
{foreach (var task in tasks){Debug.Log($"任务 {task.name}: 收集 {task.required} 件物品,奖励 {task.reward} 金币");}
}
也可以通过工具自动生成绑定
存在一些框架(如 XLua、ToLua)支持自动生成 Lua 脚本的 API 文档和绑定代码
程序员在 Unity 中使用 XLua,会自动生成可以在 Lua 中调用的 C# 函数和变量清单。策划直接查阅清单即可知道哪些数据可以修改。
- 程序员的职责:通过绑定框架(如 XLua)将游戏数据和 Lua 脚本连接起来,并定义清晰的接口。
- 策划的职责:按照约定好的变量名和函数名,在 Lua 脚本中编写逻辑,修改数据即可。
- 工具和约定的作用:策划只需了解绑定的变量和接口,配合文档和自动生成的工具,可以轻松完成任务配置或逻辑调整。

相关文章:
自由学习记录(25)
只要有修改,子表就不用元表的参数了,用自己的参数(只不过和元表里的那个同名) 子表用__index“继承”了父表的值,此时子表仍然是空表 一定是创建这样一个同名的变量在原本空空的子表里, 传参要传具体的变…...
关于函数式接口和编程的解析和案例实战
文章目录 匿名内部类“匿名”在哪里 函数式编程lambda表达式的条件Supplier使用示例 ConsumeracceptandThen使用场景 FunctionalBiFunctionalTriFunctional 匿名内部类 匿名内部类的学习和使用是实现lambda表达式和函数式编程的基础。是想一下,我们在使用接口中的方…...
Linux 僵尸进程和孤儿进程, 进程优先级
僵尸进程 之间在进程状态中了解到了 "僵尸状态". 那么处于僵尸状态的进程就是僵尸进程. 僵尸状态是一种特殊的进程状态, 它表示一个进程已经完成执行, 但其父进程尚未回收其终止状态. "僵尸状态" 的本质就是死亡状态. 如何理解僵尸进程: 举个例子: 一个正…...
爬虫笔记24——纷玩岛自动抢票脚本笔记
纷玩岛自动抢票,协议抢票思路实现 一、获取Authorization凭证二、几个关键的参数三、几个关键的接口获取参数v,这个参数其实可以写死,可忽略通过价位获取演出的参数信息获取观演人信息,账号提前录入即可提交订单接口 先看实现图&a…...
《白帽子讲Web安全》15-16章
《白帽子讲Web安全》15-16章 《白帽子讲Web安全》15章15、Web Server配置安全15.1、Apache安全15.2、Nginx安全15.3、jBoss远程命令执行15.4、Tomcat远程命令执行15.5、HTTP Parameter Pollution15.6、小结 第四篇 互联网公司运营安全《白帽子讲Web安全》16章16、互联网业务安全…...
计算机毕业设计Python+LSTM天气预测系统 AI大模型问答 vue.js 可视化大屏 机器学习 深度学习 Hadoop Spark
温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 温馨提示:文末有 CSDN 平台官方提供的学长联系方式的名片! 作者简介:Java领…...
大语言模型压缩技术;推理优化技术;SparseGPT算法;GPTQ算法
目录 大语言模型落地的成本、效率与效果 模型压缩技术 推理优化技术 SparseGPT算法 GPTQ算法 大语言模型落地的成本、效率与效果 模型压缩技术 模型压缩技术是大语言模型轻量化的关键。介绍了多种模型压缩方法,其中权重量化和模型稀疏化是两种主要的技术。 权重量化:权重…...
Facebook的开源项目解析:推动开发者社区的技术进步
Facebook,作为全球领先的社交平台之一,其在技术领域的创新不仅体现在产品功能的实现上,也积极推动开源社区的发展。开源项目已经成为Facebook技术战略的重要组成部分,通过开源,Facebook不仅加速了技术进步,…...
力扣--LCR 149.彩灯装饰记录I
题目 代码 /** Definition for a binary tree node. public class TreeNode { int val;TreeNode left;TreeNode right;TreeNode() {}TreeNode(int val) { this.val val; }TreeNode(int val, TreeNode left, TreeNode right) {this.val val;this.left left;this.right ri…...
Rust SQLx CLI 同步迁移数据库
上文我们介绍了SQLx及SQLite,并介绍了如何使用代码同步迁移数据库。本文介绍Sqlx cli 命令行工具,介绍如何安装、使用,利用其提供的命令实现数据表同步迁移。Java生态中有flyway, sqlx cli 功能类似,利用命令行工具可以和其他语言…...
批量生成不同用户的pdf 文件(html样式)
技术 selenium thymeleaf itextpdf chromedriver 使用thymeleaf 将动态数据替换 使用selenium chromedriver 进行js ,css等逻辑运算后渲染视图 使用itextpdf 将html 转为pdf 文件 html模板 <!DOCTYPE html> <html xmlns:th"http://www.thymeleaf…...
混淆零碎知识点
minifyEnabled true //混淆开关 zipAlignEnabled true // Zipalign优化 shrinkResources true // 移除无用的resource文件 (必须要混淆开了之后才才可以设置为true) proguard-rules.pro 为混淆文件 //整个文件保留 不被混淆 -keep class com.cn…...
排序算法2
排序算法1-CSDN博客 排序算法1中提及的是较为基础(暴力实现,复杂度较高)的排序算法,不适合于数据量较大的场景,比如序列长度达到1e5 接下来以蓝桥另一道题目来理解其它的排序算法 蓝桥3226 蓝桥账户中心 样例 5 1 5 9 3 7 4、快速排序 快速排…...
【Web开发基础学习——corsheaders 应用的理解】
Web开发基础学习系列文章目录 第一章 基础知识学习之corsheaders 应用的理解 文章目录 Web开发基础学习系列文章目录前言一、使用1.1 安装1.2 配置 二、功能总结 前言 corsheaders 是一个 Django 第三方应用,用于处理跨域资源共享 (CORS)。CORS 是一种机制&#x…...
Redis和MySQL之间如何进行数据同步
原因 为什么要进行Redis和MySQL的数据同步? 性能优化:MySQL是关系型数据库,数据读取和存储相对复杂;Redis是内存数据库,读写速度极快,将热点数据存在Redis,可以大大提高系统的访问速度。 数据…...
css:转换
转换 移动 /* transform: translate(100px, 200px); */transform: translateX(100px);transform: translateY(100px); /*一个意思*/ 如果后面跟百分数的意思是移动盒子自身x/y方向长度的百分比,可以用作子绝父相控制盒子水平居中垂直居中 translate里的xy值是相对…...
状态管理与存储:Vuex 和 sessionStorage
1. sessionStorage 存储位置 sessionStorage 是浏览器提供的 Web Storage API 的一部分,用于在一个会话期间存储数据。数据保存在浏览器的 内存 中,而不是在硬盘上,且其生命周期仅限于当前浏览器标签页。数据在浏览器窗口或标签页关闭时会被…...
Redis和MySQL保持一致性的延迟双删(Delay Double Delete)策略
Redis和MySQL保持一致性的延迟双删(Delay Double Delete)策略,是一种在数据更新或删除时为了保证数据一致性而采取的方法。以下是延迟双删的过程和原理的详细解释: 一、过程 第一次删除缓存: 当需要更新数据库中的数据…...
快速理解微服务中Fegin的概念
一.由来 1.在传统的架构里面,我们是通过使用RestTemplate来访问其他的服务,但是这种方式就存在了一个很大的缺陷,也就是被调用方如果发生了服务的迁移(IP和端口发生了变化),那么调用方也需要同步的在代码里面进行修改,…...
新增工作台模块,任务中心支持一键重跑,MeterSphere开源持续测试工具v3.5版本发布
2024年11月28日,MeterSphere开源持续测试工具正式发布v3.5版本。 在这一版本中,MeterSphere新增工作台模块,工作台可以统一汇总系统数据,提升测试数据的可视化程度并增强对数据的分析能力,为管理者提供测试工作的全局…...
日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战
在现代战争中,电磁频谱已成为继陆、海、空、天之后的 “第五维战场”,雷达作为电磁频谱领域的关键装备,其干扰与抗干扰能力的较量,直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器,凭借数字射…...
SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...
Redis数据倾斜问题解决
Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中,部分节点存储的数据量或访问量远高于其他节点,导致这些节点负载过高,影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决
Spring Cloud Gateway 中自定义验证码接口返回 404 的排查与解决 问题背景 在一个基于 Spring Cloud Gateway WebFlux 构建的微服务项目中,新增了一个本地验证码接口 /code,使用函数式路由(RouterFunction)和 Hutool 的 Circle…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
回溯算法学习
一、电话号码的字母组合 import java.util.ArrayList; import java.util.List;import javax.management.loading.PrivateClassLoader;public class letterCombinations {private static final String[] KEYPAD {"", //0"", //1"abc", //2"…...
MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...
《信号与系统》第 6 章 信号与系统的时域和频域特性
目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...

