<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>实战项目 on 鹿鸣青野的blog</title><link>https://www.sylgalaxy.xyz/tags/%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE/</link><description>Recent content in 实战项目 on 鹿鸣青野的blog</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Tue, 13 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.sylgalaxy.xyz/tags/%E5%AE%9E%E6%88%98%E9%A1%B9%E7%9B%AE/index.xml" rel="self" type="application/rss+xml"/><item><title>CLI 工具 flag 与 cobra</title><link>https://www.sylgalaxy.xyz/posts/go-05-01-cli-flag-cobra/</link><pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.sylgalaxy.xyz/posts/go-05-01-cli-flag-cobra/</guid><description>&lt;blockquote&gt;
&lt;p&gt;从 C++ 的 Boost.Program_options / CLI11 到 Go：标准库 flag 包入门，再上手 cobra 这个事实标准的命令行框架&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一简述"&gt;一、简述&lt;/h2&gt;
&lt;p&gt;命令行工具（CLI）是 Go 最擅长的领域之一：编译出来是单一静态二进制，启动快、分发简单，天然适合写 &lt;code&gt;git&lt;/code&gt; / &lt;code&gt;docker&lt;/code&gt; 这类开发者工具。Go 在命令行的「外挂」上做了很多设计——&lt;code&gt;os.Args&lt;/code&gt; 给你原始参数，标准库 &lt;code&gt;flag&lt;/code&gt; 包给你简单的 &lt;code&gt;-name value&lt;/code&gt; 解析，而 &lt;code&gt;spf13/cobra&lt;/code&gt;（Kubernetes、Hugo、Docker CLI 大量使用）则提供子命令、flag 继承、自动帮助和 shell 补全的完整方案。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;核心要点&lt;/strong&gt;：C++ 里解析命令行要么手写循环扫 &lt;code&gt;argv&lt;/code&gt;，要么拉 Boost.Program_options / CLI11；Go 的路径是「标准库 flag 够用即用，复杂命令行直接上 cobra」。cobra 的「命令树」思想对 C++ 开发者来说很像「用对象组合搭一棵命令路由树」。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="二c-对照速查表"&gt;二、C++ 对照速查表&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;概念&lt;/th&gt;
&lt;th&gt;C++&lt;/th&gt;
&lt;th&gt;Go&lt;/th&gt;
&lt;th&gt;关键差异&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;入口参数&lt;/td&gt;
&lt;td&gt;&lt;code&gt;int main(int argc, char* argv[])&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;func main()&lt;/code&gt; + &lt;code&gt;os.Args&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;os.Args[0]&lt;/code&gt; 是程序名，Go 是切片可遍历&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;参数解析库&lt;/td&gt;
&lt;td&gt;Boost.Program_options / CLI11&lt;/td&gt;
&lt;td&gt;&lt;code&gt;flag&lt;/code&gt;（标准库）&lt;/td&gt;
&lt;td&gt;flag 零依赖，但功能简单&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;子命令框架&lt;/td&gt;
&lt;td&gt;自己搭 / CLI11&lt;/td&gt;
&lt;td&gt;&lt;code&gt;github.com/spf13/cobra&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;cobra 是事实标准（k8s/gh/hugo 都用）&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;类型自动转换&lt;/td&gt;
&lt;td&gt;&lt;code&gt;boost::lexical_cast&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;flag 绑定即转换&lt;/td&gt;
&lt;td&gt;&lt;code&gt;flag.Int&lt;/code&gt; 自动转，无需显式 cast&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;帮助文本&lt;/td&gt;
&lt;td&gt;手动拼接打印&lt;/td&gt;
&lt;td&gt;flag / cobra 自动生成&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-h&lt;/code&gt; / &lt;code&gt;--help&lt;/code&gt; 开箱即用&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;长短选项&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-v&lt;/code&gt; / &lt;code&gt;--verbose&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;-v&lt;/code&gt; / &lt;code&gt;--verbose&lt;/code&gt; 等价&lt;/td&gt;
&lt;td&gt;flag 单双横线都认；布尔无需值&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;子命令树&lt;/td&gt;
&lt;td&gt;无标准方案&lt;/td&gt;
&lt;td&gt;cobra &lt;code&gt;AddCommand&lt;/code&gt; 层层挂载&lt;/td&gt;
&lt;td&gt;命令即对象，可嵌套&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;shell 补全&lt;/td&gt;
&lt;td&gt;无标准方案&lt;/td&gt;
&lt;td&gt;cobra &lt;code&gt;completion&lt;/code&gt; 命令&lt;/td&gt;
&lt;td&gt;生成 bash/zsh/fish 脚本&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;解析失败行为&lt;/td&gt;
&lt;td&gt;抛异常 / 返回错误码&lt;/td&gt;
&lt;td&gt;flag 默认 &lt;code&gt;ExitOnError&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;可切换到 &lt;code&gt;ContinueOnError&lt;/code&gt; 自己处理&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="三逐主题详解"&gt;三、逐主题详解&lt;/h2&gt;
&lt;h3 id="31-osargs--原始参数切片"&gt;3.1 os.Args —— 原始参数切片&lt;/h3&gt;
&lt;p&gt;任何命令行的起点。和 C++ 的 &lt;code&gt;argc/argv&lt;/code&gt; 相比，Go 把它做成了普通切片，不用数个数、不用指针算术：&lt;/p&gt;</description></item><item><title>Web 框架 Gin / Echo</title><link>https://www.sylgalaxy.xyz/posts/go-05-03-web-gin-echo/</link><pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.sylgalaxy.xyz/posts/go-05-03-web-gin-echo/</guid><description>&lt;blockquote&gt;
&lt;p&gt;从 C++ 的 Crow / Drogon 到 Go：Gin 是什么、何时该用它，以及它替你省下的那些 net/http 样板代码&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一简述"&gt;一、简述&lt;/h2&gt;
&lt;p&gt;上一篇我们把 net/http 摸了一遍——纯标准库完全能写服务，但路由到参数、JSON 绑定校验、中间件这些「每个项目都要重复一遍」的活，写得多了就烦。Gin 和 Echo 是 Go 生态里最主流的两个 Web 框架，它们把「路由分组 + 参数绑定 + 校验 + 中间件」整合成统一 API。Gin 以高性能（基于 radix tree 的路由器）和极简 API 出名，Echo 结构更规整、前后端感触更「框架味」。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;核心要点&lt;/strong&gt;：框架不改变 Go 的 Web 本质——底层还是 &lt;code&gt;http.Handler&lt;/code&gt;；Gin/Echo 只是给你一个更顺手的 &lt;code&gt;c *gin.Context&lt;/code&gt; / &lt;code&gt;e echo.Context&lt;/code&gt;。「参数绑定 + binding tag 校验」是 C++ 框架（如 Drogon）很难优雅做到的事，Go 用结构体标签声明式解决，这是最大的体验提升点。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="二c-对照速查表"&gt;二、C++ 对照速查表&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;概念&lt;/th&gt;
&lt;th&gt;C++&lt;/th&gt;
&lt;th&gt;Go&lt;/th&gt;
&lt;th&gt;关键差异&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Web 框架&lt;/td&gt;
&lt;td&gt;Crow / Drogon / cpp-httplib&lt;/td&gt;
&lt;td&gt;Gin / Echo&lt;/td&gt;
&lt;td&gt;Gin 性能强、Echo 规整&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;路由注册&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CROW_ROUTE(app, &amp;quot;/x&amp;quot;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;r.GET(&amp;quot;/x&amp;quot;, fn)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;链式+分组，表达力更强&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;路径参数&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CROW_ROUTE(app,&amp;quot;/&amp;lt;int&amp;gt;&amp;quot;)&lt;/code&gt; 回调参数&lt;/td&gt;
&lt;td&gt;&lt;code&gt;c.Param(&amp;quot;id&amp;quot;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;参数进 Handler 上下文&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;路由分组&lt;/td&gt;
&lt;td&gt;手动前缀&lt;/td&gt;
&lt;td&gt;&lt;code&gt;r.Group(&amp;quot;/api&amp;quot;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;组内共享中间件/前缀&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JSON 返回&lt;/td&gt;
&lt;td&gt;&lt;code&gt;app.route(...).post(...)&lt;/code&gt; 手动拼&lt;/td&gt;
&lt;td&gt;&lt;code&gt;c.JSON(200, obj)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;一行返回+自动 Content-Type&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;参数绑定&lt;/td&gt;
&lt;td&gt;手写解析字段&lt;/td&gt;
&lt;td&gt;&lt;code&gt;c.ShouldBindJSON(&amp;amp;req)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;结构体 tags 声明式映射&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;参数校验&lt;/td&gt;
&lt;td&gt;手写 if 判断&lt;/td&gt;
&lt;td&gt;&lt;code&gt;binding:&amp;quot;required&amp;quot;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;tag 驱动，绑定即校验&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;中间件&lt;/td&gt;
&lt;td&gt;手动包装 / 框架回调&lt;/td&gt;
&lt;td&gt;&lt;code&gt;r.Use(mw)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;全局/组/路由三级粒度&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;panic 恢复&lt;/td&gt;
&lt;td&gt;手动 try/catch&lt;/td&gt;
&lt;td&gt;&lt;code&gt;gin.Recovery()&lt;/code&gt; 内置&lt;/td&gt;
&lt;td&gt;框架默认就带&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="三逐主题详解"&gt;三、逐主题详解&lt;/h2&gt;
&lt;h3 id="31-gin-起步--一个能跑的-hello"&gt;3.1 Gin 起步 —— 一个能跑的 Hello&lt;/h3&gt;
&lt;p&gt;安装并写最小服务：&lt;/p&gt;</description></item><item><title>数据库接入 database/sql · gorm · sqlx</title><link>https://www.sylgalaxy.xyz/posts/go-05-04-database-sql-gorm-sqlx/</link><pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.sylgalaxy.xyz/posts/go-05-04-database-sql-gorm-sqlx/</guid><description>&lt;blockquote&gt;
&lt;p&gt;从 C++ 的 sqlite3 / libpq + 手写 ORM 到 Go：database/sql 抽象层 + 驱动隔离，数据访问可以有一份标准答案&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一简述"&gt;一、简述&lt;/h2&gt;
&lt;p&gt;Go 数据库世界的中心是 &lt;code&gt;database/sql&lt;/code&gt;——一个&lt;strong&gt;驱动无关的 SQL 访问抽象层&lt;/strong&gt;。就像 C++ 里 &lt;code&gt;sqlite3_open&lt;/code&gt;、&lt;code&gt;PQconnectdb&lt;/code&gt; 各写各的，Go 则约定「先 &lt;code&gt;sql.Open&lt;/code&gt; 拿到抽象连接，然后 Query/Exec/事务全走同一套接口」，不同数据库只是&lt;strong&gt;换一个驱动 import 和连接串&lt;/strong&gt;。sqlx 在其上补了「结构体 ↔ 行」的便捷映射；gorm 则是全功能 ORM（自动建表、关联、迁移），适合快速开发。三者是「底层 → 便捷 → 全自动」的一条谱系。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;核心要点&lt;/strong&gt;：先记住 &lt;code&gt;database/sql&lt;/code&gt; 的三个纪律——&lt;strong&gt;连接池要调&lt;/strong&gt;、&lt;strong&gt;行/stmt/tx 用后必关&lt;/strong&gt;、&lt;strong&gt;占位符随驱动变化&lt;/strong&gt;（MySQL 用 &lt;code&gt;?&lt;/code&gt;，PostgreSQL 用 &lt;code&gt;$1&lt;/code&gt;）。在这之上，sqlx 与 gorm 都是锦上添花。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="二c-对照速查表"&gt;二、C++ 对照速查表&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;概念&lt;/th&gt;
&lt;th&gt;C++&lt;/th&gt;
&lt;th&gt;Go&lt;/th&gt;
&lt;th&gt;关键差异&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;数据库接口&lt;/td&gt;
&lt;td&gt;sqlite3.h / libpq 各一套&lt;/td&gt;
&lt;td&gt;&lt;code&gt;database/sql&lt;/code&gt; 标准库&lt;/td&gt;
&lt;td&gt;统一抽象，换库只换驱动/连接串&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;连接池&lt;/td&gt;
&lt;td&gt;自己写 thread pool&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sql.DB&lt;/code&gt; 自带 + &lt;code&gt;SetMaxOpenConns&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;连接池是 &lt;code&gt;DB&lt;/code&gt; 的默认行为&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查询单行&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sqlite3_step&lt;/code&gt; + 手动取列&lt;/td&gt;
&lt;td&gt;&lt;code&gt;db.QueryRow(...).Scan(&amp;amp;v)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Scan 一次到位&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;查询多行&lt;/td&gt;
&lt;td&gt;每列手动转换&lt;/td&gt;
&lt;td&gt;&lt;code&gt;rows.Next()&lt;/code&gt; + &lt;code&gt;rows.Scan&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;循环+Scan，模板化&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;预处理&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sqlite3_prepare_v2&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;db.Prepare&lt;/code&gt; + &lt;code&gt;stmt.Exec&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;语义一致，但事务内惯用 tx 级 prepare&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;事务&lt;/td&gt;
&lt;td&gt;&lt;code&gt;BEGIN/COMMIT/ROLLBACK&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;db.Begin()&lt;/code&gt; + &lt;code&gt;tx.Commit/Rollback&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;要 &lt;code&gt;defer tx.Rollback()&lt;/code&gt; 做兜底&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;结构体映射&lt;/td&gt;
&lt;td&gt;手写行→struct 拷贝&lt;/td&gt;
&lt;td&gt;sqlx &lt;code&gt;Get&lt;/code&gt;/&lt;code&gt;Select&lt;/code&gt; 自动映射&lt;/td&gt;
&lt;td&gt;tag &lt;code&gt;db:&amp;quot;col&amp;quot;&lt;/code&gt; 声明式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ORM&lt;/td&gt;
&lt;td&gt;手写/第三方（如 sqlpp11）&lt;/td&gt;
&lt;td&gt;GORM（AutoMigrate/关联）&lt;/td&gt;
&lt;td&gt;自动建表、crud、迁移&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;错误处理&lt;/td&gt;
&lt;td&gt;返回码&lt;/td&gt;
&lt;td&gt;&lt;code&gt;err != nil&lt;/code&gt; 全链路&lt;/td&gt;
&lt;td&gt;每步都要查&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="三逐主题详解"&gt;三、逐主题详解&lt;/h2&gt;
&lt;h3 id="31-databasesql-起步--open-与连接池"&gt;3.1 database/sql 起步 —— Open 与连接池&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;sql.Open&lt;/code&gt; 并不会真的连数据库（&lt;code&gt;Ping&lt;/code&gt; 才触发真实连接），它返回的 &lt;code&gt;*sql.DB&lt;/code&gt; 是一个&lt;strong&gt;连接池句柄&lt;/strong&gt;：&lt;/p&gt;</description></item><item><title>原生 HTTP 服务 net/http</title><link>https://www.sylgalaxy.xyz/posts/go-05-02-http-net-http/</link><pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.sylgalaxy.xyz/posts/go-05-02-http-net-http/</guid><description>&lt;blockquote&gt;
&lt;p&gt;从 C++ 的 Boost.Beast / Crow 到 Go：标准库就是一套完整的 HTTP 服务器，Handler 即函数签名&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一简述"&gt;一、简述&lt;/h2&gt;
&lt;p&gt;在 C++ 里写 HTTP 服务要选库（Boost.Beast 偏底层、Crow 要自己搭路由、Drogon 大而全），而在 Go 里&lt;strong&gt;标准库 &lt;code&gt;net/http&lt;/code&gt; 就是一个能上生产的基础 HTTP 服务框架&lt;/strong&gt;——路由、请求解析、响应写出、超时控制、优雅关闭全都有。它的核心哲学是「一个 &lt;code&gt;http.Handler&lt;/code&gt; 就是一个 http.ResponseWriter 参数 + 一个 *http.Request 参数的函数」，一切中间件、路由、框架都是这个接口的装饰与组合。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;核心要点&lt;/strong&gt;：&lt;code&gt;Handler&lt;/code&gt; 是唯一的核心接口。Go 1.22 起 &lt;code&gt;http.ServeMux&lt;/code&gt; 原生支持「方法 + 路径」路由（&lt;code&gt;&amp;quot;GET /users/{id}&amp;quot;&lt;/code&gt;），标准库写 REST 服务不再需要任何第三方框架。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="二c-对照速查表"&gt;二、C++ 对照速查表&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;概念&lt;/th&gt;
&lt;th&gt;C++&lt;/th&gt;
&lt;th&gt;Go&lt;/th&gt;
&lt;th&gt;关键差异&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;HTTP 库&lt;/td&gt;
&lt;td&gt;Boost.Beast / Crow / Drogon / cpp-httplib&lt;/td&gt;
&lt;td&gt;&lt;code&gt;net/http&lt;/code&gt; 标准库&lt;/td&gt;
&lt;td&gt;开箱即用，零依赖起服务&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;处理器&lt;/td&gt;
&lt;td&gt;继承 handler / 回调&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http.Handler&lt;/code&gt; 接口 + &lt;code&gt;http.HandlerFunc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;函数签名即处理器&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;路由&lt;/td&gt;
&lt;td&gt;Crow 手动匹配 / router 库&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http.NewServeMux&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Go 1.22+ 支持方法路由&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;路径参数&lt;/td&gt;
&lt;td&gt;&lt;code&gt;:id&lt;/code&gt; 需框架支持&lt;/td&gt;
&lt;td&gt;&lt;code&gt;r.PathValue(&amp;quot;id&amp;quot;)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;ServeMux 通配符 &lt;code&gt;{id}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;服务对象&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Crow::run()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http.Server&lt;/code&gt; 结构体&lt;/td&gt;
&lt;td&gt;超时/监听全是 Server 字段&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;会话/keep-alive&lt;/td&gt;
&lt;td&gt;手管 socket&lt;/td&gt;
&lt;td&gt;自动，&lt;code&gt;IdleTimeout&lt;/code&gt; 管空闲连接&lt;/td&gt;
&lt;td&gt;默认开启&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;JSON 响应&lt;/td&gt;
&lt;td&gt;序列化库 + 手动 header&lt;/td&gt;
&lt;td&gt;&lt;code&gt;json.NewEncoder(w).Encode(v)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;一行流式写出&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;中间件&lt;/td&gt;
&lt;td&gt;手写装饰器 / Crow 外挂&lt;/td&gt;
&lt;td&gt;&lt;code&gt;func(http.Handler) http.Handler&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;纯函数包裹，标准模式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;优雅关闭&lt;/td&gt;
&lt;td&gt;自行实现&lt;/td&gt;
&lt;td&gt;&lt;code&gt;srv.Shutdown(ctx)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;标准库内置，等待在飞请求&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="三逐主题详解"&gt;三、逐主题详解&lt;/h2&gt;
&lt;h3 id="31-最小-http-服务--handler-与-handlerfunc"&gt;3.1 最小 HTTP 服务 —— Handler 与 HandlerFunc&lt;/h3&gt;
&lt;p&gt;任何 HTTP 服务都绕不开这两个类型：&lt;/p&gt;</description></item><item><title>综合项目实战记录（短链接服务）</title><link>https://www.sylgalaxy.xyz/posts/go-05-05/</link><pubDate>Tue, 13 Oct 2026 00:00:00 +0000</pubDate><guid>https://www.sylgalaxy.xyz/posts/go-05-05/</guid><description>&lt;blockquote&gt;
&lt;p&gt;把前面四篇的东西缝合起来：一个「从需求到 Docker 部署」的完整短链接服务，走一遍 Go 工程化的真实流程&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="一简述"&gt;一、简述&lt;/h2&gt;
&lt;p&gt;短链接服务是一个完美的「毕业设计」：需求明确、覆盖路由/存储/并发/测试/构建全链路、不引入任何第三方 Web 框架也能跑（正适合巩固 net/http）。本文按真实开发顺序走：&lt;strong&gt;需求分析 → 目录设计 → 存储接口 → 短码生成 → HTTP 路由 → 计数 → 单元测试 → go mod → 构建与 Docker&lt;/strong&gt;。&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;核心要点&lt;/strong&gt;：这个项目刻意只用标准库写 HTTP（把 &lt;a href="02-%E5%8E%9F%E7%94%9FHTTP%E6%9C%8D%E5%8A%A1-net-http.md"&gt;02-原生HTTP服务-net-http&lt;/a&gt; 练扎实），存储接口先给内存实现、日后可平移到 &lt;a href="04-%E6%95%B0%E6%8D%AE%E5%BA%93%E6%8E%A5%E5%85%A5-database-sql-gorm-sqlx.md"&gt;04-数据库接入-database-sql-gorm-sqlx&lt;/a&gt; 的 database/sql/gorm。它演示的是 Go 工程化的&lt;strong&gt;结构&lt;/strong&gt;：&lt;code&gt;cmd/&lt;/code&gt; 装入口、&lt;code&gt;internal/&lt;/code&gt; 装业务、&lt;code&gt;store&lt;/code&gt; 是抽象边界。&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h2 id="二c-对照速查表"&gt;二、C++ 对照速查表&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;概念&lt;/th&gt;
&lt;th&gt;C++&lt;/th&gt;
&lt;th&gt;Go&lt;/th&gt;
&lt;th&gt;关键差异&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;工程布局&lt;/td&gt;
&lt;td&gt;src/ + CMake targets&lt;/td&gt;
&lt;td&gt;&lt;code&gt;cmd/&lt;/code&gt; + &lt;code&gt;internal/&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;目录即包，internal 强制隔离&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;抽象接口&lt;/td&gt;
&lt;td&gt;抽象基类/接口类&lt;/td&gt;
&lt;td&gt;&lt;code&gt;interface{}&lt;/code&gt; 接口（store.URLStore）&lt;/td&gt;
&lt;td&gt;鸭子类型式，一个接口多个实现&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;短码生成&lt;/td&gt;
&lt;td&gt;自写 base62&lt;/td&gt;
&lt;td&gt;自写（本项目实现）&lt;/td&gt;
&lt;td&gt;逻辑两端一致，关注冲突处理&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;重定向&lt;/td&gt;
&lt;td&gt;手写响应头 &lt;code&gt;Location&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;http.Redirect(w, r, url, 302)&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;标准库一行&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;并发安全&lt;/td&gt;
&lt;td&gt;&lt;code&gt;std::mutex&lt;/code&gt; / &lt;code&gt;std::atomic&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;sync.RWMutex&lt;/code&gt; + map&lt;/td&gt;
&lt;td&gt;读写锁分离，并发读不死锁&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;单元测试&lt;/td&gt;
&lt;td&gt;gtest/test framework&lt;/td&gt;
&lt;td&gt;&lt;code&gt;testing&lt;/code&gt; + &lt;code&gt;go test&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;table-driven 是惯例&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;构建&lt;/td&gt;
&lt;td&gt;CMake/ninja&lt;/td&gt;
&lt;td&gt;&lt;code&gt;go build ./cmd/server&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;单二进制，静态链接&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;容器化&lt;/td&gt;
&lt;td&gt;手写 Dockerfile 依赖编译环境&lt;/td&gt;
&lt;td&gt;&lt;code&gt;golang&lt;/code&gt; builder 镜像 + 多阶段&lt;/td&gt;
&lt;td&gt;官方镜像成熟，CGO 关掉即纯静态&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id="三逐主题详解"&gt;三、逐主题详解&lt;/h2&gt;
&lt;p&gt;本项目按「需求 → 结构 → 代码 → 测试 → 构建 → 部署」的顺序推进，每一小步都有可直接运行的代码片段。&lt;/p&gt;</description></item></channel></rss>