# 奇语言 Qi — 完整语言参考(LLM 可读版) 版本 2026.07.03-2 · 官网 https://qilang.org/ · 源码 https://github.com/qilang-project/qi 本文所有代码均在真实编译器上 `qi run` 验证通过。速成规则见 https://qilang.org/llms.txt 奇语言(Qi)= 100% 中文关键字、经 LLVM 21(inkwell 后端)编译为原生可执行文件的编译型语言。 内存管理:ARC(自动引用计数)默认开启。异常机制完整(尝试/捕获/最终/抛出)。 标点同时支持英文 `; : ( ) { } ,` 与中文 `; : ( ) 【 】 ,`(全角 = 不行,赋值只能半角 =)。注释 `//` 与 `/* */`。 ═══════════════════════════════════════ 一、程序结构 ═══════════════════════════════════════ 可执行程序必须 `包 主程序;` 开头 + `函数 入口()` 入口(不是 main/主函数): 包 主程序; 函数 入口() { 打印行("你好, 奇语言!"); } 库包用自己的包名、不写 入口、对外函数加 `公开`。打印行/打印 是全局内建,无需导入。 ═══════════════════════════════════════ 二、变量、常量与类型 ═══════════════════════════════════════ 变量 名字 = "Qi"; // 可变,类型推断 变量 年龄: 整数 = 10; // 显式类型 常量 PI = 3.14159; // 不可变,必须初始化 变量 激活: 布尔 = 真; // 布尔字面量 真/假 类型表:整数(i64,默认 64 位) 浮点数(f64) 字符串(UTF-8,ARC 管理) 布尔(i1) 字节 短整数 空(void)。 - FFI 布尔型函数(如 文本.包含)返回整数 1/0,判断写 `== 1`。 - 全局常量/变量支持,顶层声明,函数内直接读写。 - 字符串 `+` 拼接,任一侧是字符串即可直接拼数字:`打印行("年龄: " + 30);` - 类型转换内建(唯一可靠方式,`作为` 转换不生成代码): 整数转字符串(42) 浮点数转字符串(3.7) 字符串转整数("123") 字符串转浮点数("1.25") 浮点数转整数(3.7)截断 整数转浮点数(2) ═══════════════════════════════════════ 三、控制流 ═══════════════════════════════════════ 如果 x > 10 { 打印行("大于10"); } 否则 { 打印行("其他"); } else-if 链的真实语法是 `否则如果` 后再写一个 `如果`(LALR 怪产物),且链尾必须有 否则;推荐直接写嵌套 `否则 { 如果 ... }`。 当(while)是唯一计数循环手段: 变量 i = 0; 当 i < 10 { i = i + 1; } - 没有 `0..10` 区间语法(`对于 i 在 0..3` 解析报错)。没有 `循环 {}`(关键字保留但未实现)。 - `跳出`/`继续` 可用(2026.07.03 起):`当` 与 `对于` 循环体内均有效,`继续` 在 `对于` 中正确步进不死循环;嵌套循环只作用于最内层;循环体外使用是编译错误。 对于...在 仅用于数组遍历(含变参): 对于 x 在 [10, 20, 30] { 打印行(x); } 匹配(match)——2026.07.03 起可用。支持整数/浮点/布尔/字符/字符串字面量分支、守卫、`_` 通配、变量绑定兜底;块尾分号可选,只能作语句(不能 变量 x = 匹配 ...)。不支持的模式(结构体解构、或模式 `2 | 3`)会编译报错而非静默: 函数 描述(n: 整数): 字符串 { 匹配 n { 1 => { 返回 "壹"; } k 如果 k > 100 => { 返回 "大数"; } // 守卫 _ => { 返回 "其他"; } } } 字符串同样可匹配(内部用运行时比较):`匹配 s { "你好" => { ... } _ => { ... } }` ═══════════════════════════════════════ 四、函数、闭包 ═══════════════════════════════════════ 函数 加法(x: 整数, y: 整数): 整数 { 返回 x + y; } 函数 打招呼(名字: 字符串) { 打印行("你好," + 名字); } // 无返回值可省 : 类型 函数 问候(名字: 字符串, 前缀: 字符串 = "您好") { ... } // 默认参数 函数 求和(数字...: 整数): 整数 { // 变参:收成数组,须最后一个参数 变量 总 = 0; 对于 n 在 数字 { 总 = 总 + n; } 返回 总; } 函数作为值/闭包——函数类型标注 `函数(参数类型,...): 返回类型`;闭包 `闭包(参数): 返回类型 { ... }`: 函数 应用(f: 函数(整数): 整数, x: 整数): 整数 { 返回 f(x); } 函数 翻倍(x: 整数): 整数 { 返回 x * 2; } 函数 入口() { 打印行(应用(翻倍, 10)); // 20 具名函数作值 变量 基数 = 100; 变量 加基数 = 闭包(x: 整数): 整数 { 返回 x + 基数; }; // 捕获环境,ARC 管理 打印行(应用(加基数, 5)); // 105 } 坑:闭包存进变量后不能直接调用(报「未定义的函数」),必须作为 函数(...) 类型参数传给函数后才能调。 ═══════════════════════════════════════ 五、结构体与方法 ═══════════════════════════════════════ 字段声明 C 式 `类型 字段;`,方法 Go 风格接收者(接收者名可用 自己/自身/自我): 类型 用户 { 字符串 姓名; 整数 年龄; } 函数 (自己 用户) 简介(): 字符串 { 返回 自己.姓名 + "(" + 自己.年龄 + "岁)"; } 函数 入口() { 变量 甲 = (用户 { 姓名: "张三", 年龄: 30 }); // 字面量必须括号包裹 打印行(甲.简介()); 甲.年龄 = 31; // 字段赋值 OK 变量 乙 = 新建 用户 { 姓名: "李四", 年龄: 25 }; // 新建 形式不用括号 } 返回结构体字面量同样要括号包裹。`枚举` 是保留字但未实现——用整数常量模拟。 ═══════════════════════════════════════ 六、异常处理(完整可用) ═══════════════════════════════════════ setjmp/longjmp 实现,同线程内跨函数传播。抛出的是字符串表达式: 函数 除法(a: 整数, b: 整数): 整数 { 如果 b == 0 { 抛出 "除数不能为零"; } 返回 a / b; } 函数 入口() { 尝试 { 打印行(除法(10, 0)); } 捕获 错误 { // 捕获 变量名(任意标识符);块内可再抛/再套 尝试 打印行("捕获到异常: " + 错误); } 最终 { // 最终 可选 打印行("清理完成"); } } 未捕获的 抛出 打印「未捕获的异常」并 abort。 ═══════════════════════════════════════ 七、数组与可变列表 ═══════════════════════════════════════ 变量 数列 = [64, 34, 25, 12]; 打印行(数列[0]); // 读下标 OK 打印行(数列.长度); // .长度 属性 对于 n 在 数列 { ... } `数列[1] = 99` 不支持(下标写)。可变序列用 标准库.列表: 导入 标准库.列表 作为 列表库; // 「列表」是类型关键字,必须别名 变量 表 = 列表库.创建整数列表(); 列表库.添加整数(表, 64); 列表库.设置整数(表, 0, 99); 打印行(列表库.获取整数(表, 0)); 列表库.删除列表(表); ═══════════════════════════════════════ 八、并发与异步 ═══════════════════════════════════════ goroutine 跑在全局 tokio 多线程运行时(worker 数 = CPU 核数,QI_ASYNC_WORKERS 可调)。 启动(goroutine)——只有 `启动 函数调用(实参);` 一种形式,没有 启动 {块}: 启动 干活(1); 启动 干活(2); 主协程退出即整个进程退出——必须用 睡眠/等待组/通道 收尾。 通道——创建 通道<整数>() 或 通道<整数>(容量);发送 `信道 <- 值`;接收 `<- 信道`(阻塞): 函数 生产者(信道: 通道<整数>) { 信道 <- 42; } 函数 入口() { 变量 信道 = 通道<整数>(); 启动 生产者(信道); 打印行(<- 信道); // 42 } 坑:只有 通道<整数> 可用(字符串/浮点通道 LLVM 校验失败,传字符串借 JSON/哈希表句柄中转); 容量只是元数据,底层无界队列,发送永不阻塞;选择(select)自 2026.07.03 起可用:非阻塞轮询,支持 默认(无就绪立即走)与 超时(毫秒) 分支,皆无则阻塞;分支 Go 风格冒号,体为裸语句列表(不带花括号)。示例: 选择 { 情况 v := <-通道甲: 打印行(v); 情况 超时(500): 打印行(0); 默认: 打印行(-1); } 未来 与 等待——异步函数 = 返回类型标注 未来 的普通函数;支持 整数/浮点数/布尔/字符串: 函数 慢计算(x: 整数): 未来<整数> { 返回 x * x; } 函数 入口() { 变量 甲 = 慢计算(3); // 立即返回 future,并发跑 变量 乙 = 慢计算(4); 打印行(等待 甲 + 等待 乙); // 25 } 静态构造:未来::就绪(值)、未来::失败("消息")。async 函数内 抛出 的异常在 等待 处重新抛出,可被 尝试/捕获 接住。 goroutine 内异常不打断主协程,进全局队列(全局内建):协程异常数量() / 获取协程异常()。 带句柄形式:启动并等待协程(函数) → 等待协程/协程有异常/获取协程异常句柄。 等待组(可靠 join,全局内建): 变量 组 = 创建等待组(); 添加等待(组, 3); 启动 干活(组, 1); ... // 每个 goroutine 里调 完成(组); 等待组等待(组); 同步原语(标准库.同步,句柄式):创建原子(初值)/原子加/读原子;创建锁()/加锁/尝试加锁/解锁/销毁锁。 并发打印:单次 打印行(单个字符串) 行级原子;多参 打印行(a,b,c) 会被其他 goroutine 交错——先 + 拼串再打印。 ═══════════════════════════════════════ 九、标准库(30+ 模块) ═══════════════════════════════════════ 导入 `导入 标准库.模块名;`,调用 `模块名.函数(...)`。别名映射:字符串→文本、时间→日期、操作系统→OS、大模型→LLM。 列表/数组/字典/集合 是类型关键字,对应模块必须起别名。没有 标准库.数学——算术直接用运算符。 返回值约定(FFI):读取文件/字符串函数失败返回空串"";写入/删除/目录操作 1=成功 0=失败;布尔型 1/0;文本.查找 未找到 -1;句柄构造返回整数句柄。 输入输出:写入文件/追加文件/读取文件/文件存在/文件大小/删除文件/创建目录/删除目录/创建符号链接 文本:去空白/字节长度/字符数量/包含/替换/转大写/转小写/查找/子串(按字节!中文3字节/字)/开始于/结束于/分割(返回字符串列表句柄) JSON(句柄式):创建对象/创建数组/设置字符串|整数|布尔|浮点数|数组|对象/数组添加*/转字符串/格式化/解码/获取*/是否包含键/删除。拼 JSON 一律用此 API,别手拼字符串。 HTTP 客户端(reqwest 真实网络):获取(GET)/发送(POST)/更新(PUT)/删除(DELETE)/修补(PATCH)/请求(方法,URL,头,体) HTTP 服务器(简单阻塞式,生产用 qi-web):创建服务器(主机,端口)/接受连接/关闭服务器 网络:TCP连接(主机,端口,超时ms)/TCP读取(句柄,缓冲区大小)/TCP写入/TCP关闭/TCP监听/TCP接受连接/UDP绑定/UDP发送到/UDP接收/端口可用/获取本机IP/解析主机 时间:现在(Unix秒)/现在毫秒/格式化(时间,"%Y-%m-%d %H:%M:%S")/年月日时分秒/星期几/睡眠毫秒/解析/加秒|分钟|小时|天|周 哈希表(键为字符串,按值类型分族):创建整数表|字符串表|浮点表/设置*/获取*/包含键/表大小/删除键/清空表/释放表 列表:创建整数列表|字符串列表|浮点列表/添加*/设置*/获取*/弹出*/插入*/*列表大小/删除列表 随机:生成整数(最小,最大)/生成浮点/生成布尔/生成字符串(长度)/UUID() 加密:SHA256哈希/SHA512哈希/MD5哈希/Base64编码/Base64解码/HMAC_SHA256(数据,密钥) 正则(模式在前文本在后):是否匹配/查找/全部替换/查找全部/切割 路径:连接/文件名/扩展名/父目录/存在/是目录/是文件/绝对路径 操作系统:操作系统类型/CPU核心数/系统架构/主机名/用户名/用户主目录/临时目录/当前目录/切换目录/设置|获取环境变量/进程ID/退出程序/列出目录/加载环境文件 子进程:生成(命令,参数JSON数组)→句柄/写入行/读取行/读取行超时(句柄,ms)/存活/结束 测试:断言相等_整数(实际,期望,消息)/断言相等_字符串/断言相等_浮点/断言真/断言假/测试通过/测试失败 其他:WebSocket、MCP服务器/MCP客户端、数据库(SQLite)、压缩(Gzip)、配置(TOML/INI)、大模型(OpenAI 兼容 LLM API)、命令行(clap 风格)、进程、环境、向量、图形化(GUI:窗口/事件/2D渲染/音频)、同步、TLS、信号、字节切片 ═══════════════════════════════════════ 十、导入与包管理 ═══════════════════════════════════════ 导入 标准库.HTTP; // 标准库(大写 HTTP) 导入 标准库.输入输出 作为 IO; // 别名(返回字符串的调用赋变量要加 : 字符串 标注) 导入 ./辅助; // 相对路径(同目录 辅助.qi) 导入 ../工具包; // 上级目录 导入 工具::{平方, 问好}; // 第三方包 destructure(唯一跨包调用方式) 公开 导入 桩; // 重导出 跨包不支持 Web::函数() 形式,只支持 destructure 后直呼函数名。 qi.toml 清单(键名中英皆可,中文键无需引号): [包] 名称 = "演示应用" 版本 = "0.1.0" 入口 = "主程序.qi" [依赖] 工具 = "../工具库" # 本地路径 Web = "github.com/liliang-cn/qi-web@v1.0" # 远程 host/owner/repo[@ref] Harness = { git = "https://github.com/x/y", 引用 = "v2.1", 子目录 = "harness" } - 依赖键 = 导入用的别名。`qi get` 拉取全部远程依赖并写 qi.lock(锁 commit,可复现构建);编译期绝不联网。 - 缓存:~/.qi/packages/src///@/(QI_HOME 可改根)。 - qi get github.com/x/y@v1.0 拉取并写进 qi.toml;--名 指定别名。 多文件组织:qi run 只接受入口文件。同目录多文件两条路: ① 同包自动发现——同包名 + 无 入口 + 无任何 导入 的 .qi 自动并入编译; ② 显式相对导入 导入 ./辅助;(辅助文件加 公开)。 库包:包 自己的包名; 不写 入口,对外 公开;库包的 入口 不与使用方冲突(只有入口模块发 @main)。 ═══════════════════════════════════════ 十一、工具链 ═══════════════════════════════════════ CLI(全部有中文别名): qi run 程序.qi 运行(编译并运行) qi compile 程序.qi -o 出 编译为可执行文件 qi check 程序.qi 只查语法(rustc 风格错误:行列号+源码 caret+修复提示) qi test [路径] 发现并运行 *_测.qi(-f 过滤 -v 详细) qi get [包地址] 拉取远程依赖 qi debug / qi info 选项:-O none|basic|standard|maximum(映射 O0-O3,默认 basic);-o 输出;-t/--target linux|windows|mac-os;--arch x86_64|aarch64;--release-runtime 格式化用独立二进制 qifmt(qi format 是未实现的桩):只动空白,幂等;qifmt 文件.qi / --check / --diff / -r 目录。 交叉编译(macOS → Linux,zig 链接零 Docker): qi --target linux --arch x86_64 --release-runtime compile 程序.qi -o 程序_linux 安装布局:/usr/local/bin/qi + /usr/local/lib/qi/(运行时归档),解压即用。 下载:https://github.com/qilang-project/qi/releases (2026.07.03-2,macOS arm64/Linux x64/Windows x64) 一键脚本:curl -fsSL https://raw.githubusercontent.com/qilang-project/qi/main/scripts/install.sh | bash ═══════════════════════════════════════ 十二、内存管理(ARC) ═══════════════════════════════════════ 默认开启:字符串、结构体、数组、闭包环境自动 retain/release(跨线程原子计数;字符串字面量不朽零开销)。 句柄式资源(JSON/列表/哈希表/服务器/子进程句柄)仍要手动 删除/释放表/关闭。 循环引用不回收(纯引用计数无环检测,同 Swift)——长驻进程注意打破环。 环境变量(运行编译产物时):QI_ARC=0 关闭 ARC(调试);QI_RC_REPORT=1 退出时打印活跃对象计数(检测泄漏); QI_ASYNC_WORKERS=N 协程 worker 数;QI_PACKAGES_PATH 包搜索根;QI_HOME 覆盖 ~/.qi。 ═══════════════════════════════════════ 十三、保留字地雷 ═══════════════════════════════════════ 不能作变量/函数/字段名: 结果 类型 选项 通道 未来 数组 列表 字典 集合 任务 循环 尝试 捕获 抛出 最终 返回 等待 异步 新建 选择 情况 在 作为 与 或 非 加 减 乘 除 取余 等于 不等于 大于 小于 整数 浮点数 字符串 布尔 字节 字符 指针 引用 枚举 结构体 方法 中文直觉命名最常踩:变量 结果 / 变量 乘 / 变量 数组 全报错,改 计算结果/乘法函数/数列。 例外:长度 可作标识符;类型 通道 结果 选项 可作字段名;接收者名可用 自己/自身/自我。 ═══════════════════════════════════════ 十四、生态与惯例 ═══════════════════════════════════════ 框架(全部用奇语言写,仓库根有 SKILL.md): - qi-web:Express/FastAPI 风格 Web 框架,实测 147k RPS(达 Go net/http 90%)。导入 Web::{创建应用,配置,获取,文本,运行应用};handler 签名 函数(上下文): 响应。路由 path 用 ASCII。 - qi-cli:Cobra 风格命令行框架。导入 CLI::{创建应用,创建命令,执行};handler 签名 函数(上下文): 整数。 - qi-harness:LLM Agent 框架。导入 Harness::{大模型,开启会话,创建代理,简单问,关闭代理};密钥从环境变量读。 - qi-lsp + VSCode 扩展、qi-test 测试框架、qi-gui(标准库.图形化)。 Agent skill 安装:npx skills add https://github.com/qilang-project/qi-lang 惯例: - 示例/部署端口一律用 3000 以上随机高位(3076/6759/43510/43719),严禁 8080/3000/8000。 - 性能实测(2026-07,Apple M2 Pro):fib(40) 0.28s(Go 1.26 为 0.32s,Node 24 为 0.71s);qi-web 147k RPS。 - 验证生成的代码:qi check 文件.qi → qi run 文件.qi。