## **KQCode**
除了工具类,有些时候封装类依旧还是有些用处的。此模组中提供了一个`KQCode`封装类,同样的,其命名原则也是为了避免与`CQCode`混淆并遵循某些命名规则。
<br>
`KQCode`在模组`1.8.0`版本的时候变更为了接口类型,并提供若干不同形式的实现类。
- ##### **参数可变性**
<hr>
KQCode实现了 **`Map<String, String>`** 接口与 **`CharSequence`** 接口,但是从 **`1.5.0-1.15`** 版本开始,KQCode被更改为了**不可变类**,因此一个普通的KQCode实例是不可以执行put、remove等修改操作的。
你可以通过KQCode实例的`mutable()`方法将`KQCode`转化为参数可变的`MutableKQCode`,或者通过`immutable()`方法转化为参数不可变的`KQKode`实例。
```java
// 作为map使用
Map<String, String> kqMap = new KQCode("at", "qq=123456789");
System.out.println(kqMap);
// 作为CharSequence使用
CharSequence kqCharSequence = new KQCode("at", "qq=123456789");
System.out.println(kqCharSequence);
```
<br><br>
- ##### **构建KQCode**
<hr>
~~`KQCode`是一个封装类,因此它不是单例的。如果要使用它,可通过其构造方法或静态方法获取。~~
`KQCode`是一个接口类型,你可以:
- 通过`KQCodeUtils`的与`kq`相关的方法(例如`toKq(...)`)构建一个`KQCode`实例
- 使用模组内提供的实现类(例如`FastKQCode`、`MapKQCode`、`EmptyKQCode`)的静态方法构建一个`KQCode`实例
- 自行实现`KQCode`接口
由于使用`KQCodeUtils`构建实例的实例代码在`CQ码操作工具类`章节里已经出现过了,此处便只展示使用第二种方法的示例:
```java
// 通过KQCode静态方法构建:
// 通过一个完整的CQ码字符串构建
KQCode at = KQCode.of("[CQ:at,qq=123456]");
// 通过一个没有参数的纯类型构建
KQCode share = KQCode.ofType("share");
// 通过实现类构建:
// 通过一个完整的CQ码字符串构建, 使用的是FastKQCode
FastKQCode fastKQCodeAt = FastKQCode.byCode("[CQ:at,qq=123456789]");
// 通过一个完整的CQ码字符串构建,使用的是MapKQCode
MapKQCode mapKQCodeAt = MapKQCode.byCode("[CQ:at,qq=123456789]");
// 通过类型和参数字符串构建,使用的是MapKQCode
MapKQCode mapByParamAt = MapKQCode.byParamString("at", "qq=123", "display=@bot");
// 通过类型和Map参数列表构建,使用的是MapKQCode
Map<String, String> params = new HashMap<>();
params.put("qq", "123456789");
MapKQCode mapByMapAt = MapKQCode.byMap("at", params);
// 通过一个完整的CQ码字符串构建(可变类型),使用的是MutableMapKQCode
MutableMapKQCode mutableMapKQCodeAt = MapKQCode.mutableByCode("[CQ:at,qq=123456789]");
// 通过类型和参数字符串构建(可变类型),使用的是MutableMapKQCode
MapKQCode mutableMapByParamAt = MapKQCode.mutableByParamString("at", "qq=123", "display=@bot");
// 通过类型和Map参数列表构建(可变类型),使用的是MutableMapKQCode
Map<String, String> params2 = new HashMap<>();
params.put("qq", "123456789");
MapKQCode mutableMapByMapAt = MapKQCode.mutableByMap("at", params2);
// 构建一个没有参数的KQCode, 使用的是EmptyKQCode
EmptyKQCode dice = new EmptyKQCode("dice");
```
>[info] 除了通过静态方法与`KQCodeUtils`的方法,你也可以使用载体为`KQCode`类型的模板,例如`KQCodeUtils`的`getKqCodeTemplate()`
>[info] 关于`FastKQCode`、`MapKQCode`、`MutableMapKQCode`、`EmptyKQCode`之间的区别,可以参考他们各自的doc注释。
<br><br>
- ##### **KQCode与CQCode**
<hr>
除了普通的通过字符串构建,KQCode在依赖了simple-robot核心的情况下可以实现与`CQCode`相互转化。
**但是一切与`CQCode`的相互操作均不被推荐,并可能会在未来被删除。**
```java
// 构建一个at的CQCode
final CQCode cqCodeAt = CQCode.of(CQCodeTypes.at, new String[]{"qq=123456789"});
System.out.println(cqCodeAt);
// 转化为KQCode
final KQCode kqCodeAt = KQCode.of(cqCodeAt);
System.out.println(kqCodeAt);
// 转回CQCode
final CQCode newCqCodeAt = kqCodeAt.toCQCode();
System.out.println(newCqCodeAt);
```
<br>
<br><br>
<br><br>
## **KQCode for DSL**
当你使用kt文件使用KQCode的时候,你可以通过偏向于DSL风格的代码来构建一个KQCode对象。
你用两种方法,第一种是提前指定CQ码的类型,而第二种则在代码块种执行。需要注意的是,如果在使用第二种方法的时候没有去指定CQ码的类型,则其类型为空字符串。
```kotlin
// import com.simplerobot.modules.utils.kqCode
// import com.simplerobot.modules.utils.params
// DSL to KQCode 1
val kq1 = kqCode("at") {
param = "key1" to "1"
param = "key2" to "2"
param = "key3" to "3"
param = "key4" to "4"
}
// DSL to KQCode 2
val kq2 = kqCode {
type = "at"
params {
param = "qq" to "1149"
param = "file" to "cq.jpg&&"
}
}
println(kq1)
println(kq2)
```
>[success] 输出结果为:
> [CQ:at,key1=1,key2=2,key3=3,key4=4]
> [CQ:at,qq=1149,file=cq.jpg&amp;&amp;]
简单来讲,即:
```kotlin
kqCode("CQ码类型") {
param = "参数1键" to "参数1值"
param = "参数2键" to "参数2值"
...
}
```
或
```kotlin
kqCode {
type ="CQ码类型"
params {
param = "参数1键" to "参数1值"
param = "参数2键" to "参数2值"
...
}
}
```
<br><br>
- 前言
- 简单介绍
- 我该如何阅读文档
- 视频教程
- 安装与使用
- 开源协议
- 免责&捐助
- 注意事项
- 版本命名规则简介
- 主要功能版本历史
- 功能指引
- 通用API与功能
- 国际化语言
- 异常
- 消息监听
- @Listen
- @OnListen模板
- @Filter
- 消息参数截取
- @Spare
- @Constr
- @Ignore
- @ListenBreak
- @ListenBreakPlugin
- @ListenBody
- 监听响应
- 成功判定与返回值
- 监听上下文
- 动态参数
- 监听消息API
- 异步监听 @Async
- 限流监听 @Limit
- 自定义Http送信器
- 枚举与类型
- 送信器
- SENDER
- SETTER
- GETTER
- 返回值
- 其他位置
- 日志与日志拦截
- 异常处理
- 依赖注入
- 自定义依赖获取
- 批量依赖载入
- 注意事项
- 常量
- 定时任务
- 自定义过滤
- 拦截器
- 拦截器总定义
- 上下文对象总定义
- 监听消息拦截
- 送信器拦截
- 监听函数拦截
- CAT码
- CQ码
- CQCode
- CQ码工具类
- CQ扩展工具类
- AppendList拼接链
- 高级内容
- 阻断机制
- 截断机制
- 自定义枚举类型
- 枚举工厂
- byName注解
- 自定义注解
- 配置
- 文件配置
- 注解配置
- 参数配置
- 多配置
- 多账号
- 自定义账号管理器
- 小心!
- 核心版本与组件如何升级核心
- 核心版本迭代指南
- 核心
- 更新日志
- jar包与依赖
- 监听消息类结构图
- 快速启动
- 模组与扩展
- 模组开发
- 现有模组
- 通用模组-延时任务
- 通用模组-CQ码工具
- 转义器
- CQ码操作工具类
- CQ码模板-CodeTemplate
- CQ码载体-KQCode
- CQ码构建器
- MQ码工具类
- 通用模组-redis-bot管理器
- 通用模组-Debugger
- Debugger-common模块
- Debugger-server模块
- Debugger-client模块
- 通用模组-钉钉机器人
- 组件-Mirai(JVM)
- 快速开始(1.13+)
- springboot-starter
- 注意事项
- 配置
- 额外的内容
- 快速回复
- 额外监听
- CQ码解析
- 组件-酷Q(QQ)-CQ HTTP API(基本失效)
- 快速开始(推荐)
- 快速开始(1.7.x以下,不推荐)
- 快速开始(Springboot启动器)
- 启动器、启动接口与配置类
- 配置
- 文件配置
- 注意事项
- 更新日志
- 额外的内容
- 自定义额外监听
- CQ送信器
- 元事件
- 监听消息类结构图
- 组件-酷Q(QQ)-JCQ(失效)
- 快速开始
- 更新日志
- 额外的内容
- JCQ日志
- 配置
- 注意事项
- 监听消息类结构图
- 组件-酷Q(QQ)-HTTP TO CQ(失效)
- 快速开始(核心1.7.x及以下)
- 启动器、启动接口与配置类
- 配置
- 文件配置
- 注意事项
- 更新日志
- 监听消息类结构图
- 组件-酷Q(QQ)-LEMOC (失效)
- 快速开始(核心1.7.x及以下)
- 配置
- 注意事项
- 更新日志
- 监听消息类结构图
- Springboot快速启动器
- 常见问题汇总
- BUG反馈
- 更新计划总览