ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

为什么 Rust 写输入法要这样设计:青简「平台无关 Core + 薄壳」架构完全解读

2026/10/5 8:06:05 拓冰建站 浏览量
为什么 Rust 写输入法要这样设计:青简「平台无关 Core + 薄壳」架构完全解读 为什么 Rust 写输入法要这样设计青简「平台无关 Core 薄壳」架构完全解读【免费下载链接】qingjian青简 Qingjian用 Rust 写的拼音输入法候选词旁多一条正在学的语言的译词项目地址: https://gitcode.com/gh_mirrors/qi/qingjian青简 Qingjian 是一款用 Rust 编写的拼音输入法它在候选词旁多显示一条学习语言的译词让你在打字的同时自然积累外语词汇。它最值得关注的设计是把「平台无关 Core 薄壳」作为第一原则词库、拼音解析、整句转换、排序和学习全部沉淀在一个不依赖任何平台 API 的 Rust Core 里而 macOS、Windows、Linux 三端各自只做一层极薄的适配壳。本文将带你完整解读这套 Rust 输入法架构的来龙去脉。一、先想清楚输入法到底要「移植」什么写一个输入法表面上是写三遍 UI实际上最大的工作量在引擎拼音怎么切分、整句候选怎么算、候选怎么排序、用户的习惯怎么学习。如果这些逻辑散落在三个平台各自的代码里每修一个排序 bug 就要改三处加一个功能就要测三遍。青简的架构约束写得很直白见 docs/design/architecture.md判断标准把 IMK 换成 TSF不应该需要改 Core 的任何一行。这就是「平台无关 Core」的定义——Core 不允许依赖任何平台 API平台层里不允许出现排序逻辑、词库访问或翻译调用。二、看目录结构一眼分清 Core 和壳青简是一个 Rust workspace顶层 Cargo.toml 里crates/和apps/的划分就是架构本身Core 侧crates/与平台完全无关crate职责crates/qingjian-core输入状态机、拼音切分、候选生成、排序、整句转换、纠错crates/qingjian-dictionary词库加载与查询crates/qingjian-lm整句 bigram 语言模型crates/qingjian-neural本地神经模型给整句候选重打分crates/qingjian-translate候选词旁那条译词学习语言crates/qingjian-learning用户词频、个人 n-gram、自动造词crates/qingjian-predict可选的云联想默认关闭crates/qingjian-format.qj数据容器mmap 零拷贝打开启动从 0.9 s 降到 50 mscrates/qingjian-render跨平台自绘候选窗口渲染crates/qingjian-platform平台共用部分配置文件、IPC 协议类型壳侧apps/尽量薄apps/macosIMK 输入法壳app / host / imk / candidates / preferencesapps/windows独立 Server 进程 TSF 文本服务 DLLapps/linux/fcitx5薄 C 插件 Rust Server 进程apps/cli命令行测试工具用来在无平台环境下验证 Core依赖方向是单向的Core 只依赖 dictionary翻译、学习、联想、语言模型全部通过 trait 从外部注入最终在apps/*里完成组装。三、「薄壳」有多薄三个平台的答案不同这是这套架构最精妙的地方——壳的厚度由系统机制决定而不是随意而定macOSCore 与壳同进程壳用objc2系列绑定直接继承IMKInputController它只做两件事把按键事件翻译成Engine::push()把候选画进自绘的 NSPanel。Core 就活在同一个进程里没有 IPC 开销。Windows壳必须进程外TSF DLL 会被加载进每一个应用进程把词库和神经模型塞进每个 Word、Edge 是不现实的。所以 Windows 采用与水杉相同的结构apps/windows/tsf 这个 DLL 只做 IPC 客户端真正的 Rust Core 跑在独立的 Server 进程里通过命名管道通信。Linux与 Windows 同构Fcitx5 是所有输入法共用的进程Core 同样跑在独立 Rust Server 里Unix socket插件只做转发——Server 崩了也不会带倒 Fcitx5。三个平台对比下来你会发现引擎代码只有一份差异被压缩进了「事件怎么进来、窗口怎么画」这两件事上。这正是薄壳设计的全部收益。四、trait 注入Core 如何不碰网络、不碰文件却拥有全部功能翻开 crates/qingjian-core/src/engine/mod.rsEngine的translator、learner等字段都是Boxdyn Trait缺省为空实现。三个关键 trait 各管一件事Translatorengine/translator.rs候选旁那条译词的提供方。注释写明「必须是纯查表级别的开销不能做网络请求」。接口是分两步的update()立即返回不带译文的候选译文异步补上——候选先到、译文后到平台层收到更新只重绘对应行。Learnerengine/learning/learner.rs用户词频、选择偏好、自动造词真实实现在 crates/qingjian-learning。Predictorengine/prediction/predictor.rs云联想。实现可以联网但接口是非阻塞的submit/poll超时即丢、不重排已有候选。Core 永远不联网。这套设计带来两条硬收益Core 的单元测试和 CLI 工具不需要任何真实词库或网络就能跑「输入优先于学习」被写进了 API 形状——翻译查询在接口层面就不可能阻塞候选生成。五、同一套协议两种部署形态qingjian-platform里的协议类型必须可序列化serdemacOS 上 Core 与壳同进程时直接函数调用Windows/Linux 上跨进程时走 IPC 消息——同一套类型两边共用。以 Windows 为例crates/qingjian-platform/src/protocol/client.rs 的ClientMessage开/关会话、按键、上屏与 protocol/server.rs 的ServerMessage按键结果、异步重绘、请求上下文就是 DLL 与 Server 之间全部通信的契约。换句话说进程内的函数调用与跨进程的消息在类型层面是同一个东西。平台差异在协议这一层被彻底抹平。六、参与开发从 CLI 开始读代码想上手这套架构建议路径是先跑 apps/clicargo run -p qingjian-cli -- kaifa直接查词不带参数进交互模式——Core 的验证不依赖跑起真实输入法再读 docs/design/architecture.md 里的 crate 依赖方向图与Engine会话 API然后按平台进入对应的壳apps/macos/README.md、apps/windows/README.md 或 apps/linux/fcitx5/README.md。七、总结这套架构给 Rust 输入法开发者的启示平台无关 Core 不是口号而是编译期约束Core 不允许依赖任何平台 API违反即架构错误壳的厚度由系统机制决定macOS 同进程、Windows/Linux 进程外 IPC引擎永远只有一份功能用 trait 注入而非硬编码翻译、学习、联想都是可选插件缺省空实现Core 测试不依赖真实数据协议即类型serde 可序列化的协议类型同时服务进程内调用与跨进程 IPC一套契约两边共用。「好好输入顺便多认识一个词」是青简的产品目标而「平台无关 Core 薄壳」是让这个目标在三端稳定落地的工程答案。【免费下载链接】qingjian青简 Qingjian用 Rust 写的拼音输入法候选词旁多一条正在学的语言的译词项目地址: https://gitcode.com/gh_mirrors/qi/qingjian创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考