[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-rust-cli-project-5-practical-steps-zh":3,"article-related-rust-cli-project-5-practical-steps-zh":31,"series-tools-871c382b-188c-4eb7-a2b6-978e0183f18f":84},{"id":4,"slug":5,"title":6,"content":7,"summary":8,"source":9,"source_url":10,"author":11,"image_url":12,"cover_image":12,"category":13,"language":14,"translated_content":11,"related_article_id":15,"keywords":16,"key_takeaways":23,"views":27,"created_at":28,"published_at":29,"topic_cluster_id":30},"871c382b-188c-4eb7-a2b6-978e0183f18f","rust-cli-project-5-practical-steps-zh","Rust CLI 天氣工具五步實作","\u003Cp data-speakable=\"summary\">這篇教你用 Cargo、Clap、Tokio、Reqwest 和 Serde 做出一個可編譯、可測試的 \u003Ca href=\"\u002Ftag\u002Frust\">Rust\u003C\u002Fa> 命令列天氣工具。\u003C\u002Fp>\u003Cp>這篇是寫給已經會另一種程式語言、想快速做出可用 Rust CLI 的開發者。你可以一路照著做，最後拿到一個能接收城市參數、發送非同步請求、輸出天氣資料，且可持續擴充的專案。\u003C\u002Fp>\u003Cp>做完之後，你會得到一個標準 Cargo 專案、基本命令列介面、可運作的非同步網路呼叫，以及一套能直接延伸成正式工具的程式骨架。\u003C\u002Fp>\u003Ch2>開始之前\u003C\u002Fh2>\u003Cul>\u003Cli>已安裝 Rust 工具鏈 1.95.0 stable，並透過 \u003Ca href=\"https:\u002F\u002Frustup.rs\u002F\">rustup\u003C\u002Fa> 管理版本\u003C\u002Fli>\u003Cli>Cargo 1.95.0、rust-analyzer、clippy、rustfmt 都已可用\u003C\u002Fli>\u003Cli>作業系統為 macOS、Linux 或 Windows 的 WSL2，且可使用 Unix-like shell\u003C\u002Fli>\u003Cli>編輯器為 VS Code 或 Neovim，並已啟用 rust-analyzer\u003C\u002Fli>\u003Cli>若天氣 API 需要驗證，請先準備好 API key\u003C\u002Fli>\u003Cli>依賴套件版本已確認：Tokio 1.40.0、Reqwest 0.12.7、Serde 1.0.210、Serde JSON 1.0.128、Clap 4.5.17、Anyhow 1.0.82\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>Step 1: 安裝 Rust 工具鏈\u003C\u002Fh2>\u003Cp>這一步的目的，是先把編譯器、套件管理器與格式化工具裝好，避免後面每一個步驟都卡在環境問題。你要先確認本機真的在用 stable 工具鏈，而不是系統預裝版本。\u003C\u002Fp>\n\u003Cfigure class=\"my-6\">\u003Cimg src=\"https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1780898582793-87p5.png\" alt=\"Rust CLI 天氣工具五步實作\" class=\"rounded-xl w-full\" loading=\"lazy\" \u002F>\u003C\u002Ffigure>\n\u003Cpre>\u003Ccode>curl --proto '=https' --tlsv1.2 -sSf https:\u002F\u002Fsh.rustup.rs | sh\nsource \"$HOME\u002F.cargo\u002Fenv\"\nrustc --version\ncargo --version\nrustup component add rust-analyzer clippy rustfmt\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>驗收時，你\u003Ca href=\"\u002Fnews\u002Fportsmouth-ai-buildout-energy-infrastructure-zh\">應該\u003C\u002Fa>看到 rustc 1.95.0 和 cargo 1.95.0，並且三個元件都能成功加入。這代表後續建立專案、檢查程式碼與自動格式化都已就緒。\u003C\u002Fp>\u003Ch2>Step 2: 建立 Cargo 專案\u003C\u002Fh2>\u003Cp>這一步的目的，是先產生一個標準的二進位 crate，\u003Ca href=\"\u002Fnews\u002Flaunch-site-rust-loot-routes-zh\">讓你\u003C\u002Fa>有乾淨的專案結構可以直接修改。Cargo 會同時建立原始碼目錄與建置設定，之後所有功能都會在這個骨架上展開。\u003C\u002Fp>\n\u003Cfigure class=\"my-6\">\u003Cimg src=\"https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1780898584930-ycpl.png\" alt=\"Rust CLI 天氣工具五步實作\" class=\"rounded-xl w-full\" loading=\"lazy\" \u002F>\u003C\u002Ffigure>\n\u003Cpre>\u003Ccode>cargo new weather_cli\ncd weather_cli\ncargo run\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>驗收時，你應該看到預設的 Hello, world! 輸出，並且專案底下出現 target\u002Fdebug\u002Fweather_cli。這代表 Cargo 已經能成功編譯並執行你的 CLI 程式。\u003C\u002Fp>\u003Ch2>Step 3: 加入命令列參數\u003C\u002Fh2>\u003Cp>這一步的目的，是讓程式不再只是固定輸出，而是能接收使用者傳入的城市名稱與選項。你會先把 Clap 接進來，建立一個可解析的參數結構，讓 CLI 真正具備互動性。\u003C\u002Fp>\u003Cpre>\u003Ccode>cargo add clap --features derive\ncargo add anyhow\n\nuse clap::Parser;\n\n#[derive(Parser, Debug)]\nstruct Args {\n    #[arg(short, long)]\n    city: String,\n}\n\nfn main() {\n    let args = Args::parse();\n    println!(\"City: {}\", args.city);\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>驗收時，你應該看到執行 cargo run -- --city Tokyo 後，畫面輸出 City: Tokyo。這代表參數已經被正確解析，Clap 的整合也沒有問題。\u003C\u002Fp>\u003Ch2>Step 4: 串接非同步天氣請求\u003C\u002Fh2>\u003Cp>這一步的目的，是把 CLI 變成真的會對外溝通的工具。你要引入 Tokio、Reqwest 與 Serde，讓程式能在非同步 runtime 中送出 HTTP 請求，並準備解析回傳資料。\u003C\u002Fp>\u003Cpre>\u003Ccode>cargo add tokio --features full\ncargo add reqwest --features json,rustls-tls\ncargo add serde --features derive\ncargo add serde_json\n\n#[tokio::main]\nasync fn main() -> anyhow::Result&lt;()&gt; {\n    let body = reqwest::get(\"https:\u002F\u002Fexample.com\u002Fweather.json\").await?.text().await?;\n    println!(\"{}\", body);\n    Ok(())\n}\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>驗收時，你應該看到一段 HTTP 回應內容，或至少能成功印出 JSON 字串。這代表非同步執行緒、網路請求與錯誤回傳都已正常運作。\u003C\u002Fp>\u003Ch2>Step 5: 格式化、檢查並輸出正式版本\u003C\u002Fh2>\u003Cp>這一步的目的，是把專案整理成可以交付的狀態。你要用 fmt、clippy、test 與 release build，確認程式碼風格一致、沒有明顯警告，且可產出最佳化執行檔。\u003C\u002Fp>\u003Cpre>\u003Ccode>cargo fmt\ncargo clippy\ncargo test\ncargo build --release\u003C\u002Fcode>\u003C\u002Fpre>\u003Cp>驗收時，你應該看到格式化完成、clippy 沒有錯誤、測試通過，並且在 target\u002Frelease\u002Fweather_cli 找到正式版執行檔。這代表你的 CLI 已經具備可維護與可發佈的基本條件。\u003C\u002Fp>\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>指標\u003C\u002Fth>\u003Cth>基準／優化前\u003C\u002Fth>\u003Cth>結果／優化後\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\u003Ctr>\u003Ctd>專案狀態\u003C\u002Ftd>\u003Ctd>尚未建立 Rust 應用\u003C\u002Ftd>\u003Ctd>可執行的 CLI 二進位檔\u003C\u002Ftd>\u003C\u002Ftr>\u003Ctr>\u003Ctd>執行模型\u003C\u002Ftd>\u003Ctd>同步占位程式\u003C\u002Ftd>\u003Ctd>Tokio 非同步 runtime\u003C\u002Ftd>\u003C\u002Ftr>\u003Ctr>\u003Ctd>依賴覆蓋\u003C\u002Ftd>\u003Ctd>沒有外部套件\u003C\u002Ftd>\u003Ctd>Clap、Reqwest、Serde、Tokio\u003C\u002Ftd>\u003C\u002Ftr>\u003Ctr>\u003Ctd>建置輸出\u003C\u002Ftd>\u003Ctd>只有除錯版\u003C\u002Ftd>\u003Ctd>最佳化 release 版\u003C\u002Ftd>\u003C\u002Ftr>\u003C\u002Ftbody>\u003C\u002Ftable>\u003Ch2>常見錯誤\u003C\u002Fh2>\u003Cul>\u003Cli>用系統套件管理器裝 Rust，結果版本太舊。修法：改用 rustup，或把 ~\u002F.cargo\u002Fbin 放到 PATH 前面，確保呼叫到正確工具鏈。\u003C\u002Fli>\u003Cli>忘記在 cargo run 後加上 --，導致參數被 Cargo 吃掉。修法：改成 cargo run -- --city Tokyo，讓應用程式自己接收參數。\u003C\u002Fli>\u003Cli>把同步函式和非同步請求混在一起，卻沒有 Tokio runtime。修法：把入口函式改成 #[tokio::main] async fn main()，並把網路呼叫放進 async 區塊。\u003C\u002Fli>\u003C\u002Ful>\u003Ch2>接下來可以看什麼\u003C\u002Fh2>\u003Cp>下一步可以把天氣資料改成真正的 \u003Ca href=\"\u002Ftag\u002Fapi\">API\u003C\u002Fa> 回應模型，加入 thiserror 做錯誤分類，再補上整合測試與 crates.io 發佈流程，讓這個 CLI \u003Ca href=\"\u002Fnews\u002Fciti-tokenization-forecast-turns-markets-onchain-zh\">變成可\u003C\u002Fa>長期維護的正式工具。\u003C\u002Fp>","這篇指南帶你用 Cargo、Clap、Tokio、Reqwest 和 Serde 做出可編譯、可測試的 Rust 命令列天氣工具。","tech-insider.org","https:\u002F\u002Ftech-insider.org\u002Frust-programming-tutorial-cli-project-2026\u002F",null,"https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1780898582793-87p5.png","tools","zh","736107e8-43ea-4213-b251-b1bbce64a7f2",[17,18,19,20,21,22],"Rust","Cargo","Clap","Tokio","Reqwest","Serde",[24,25,26],"先用 rustup 固定 Rust 工具鏈，再建立標準 Cargo 專案。","用 Clap 做參數解析，讓 CLI 先具備可操作介面。","用 Tokio、Reqwest 與 Serde 把同步範例升級成可測試的非同步網路工具。",2,"2026-06-08T06:02:31.211769+00:00","2026-06-08T06:02:31.203+00:00","269e8a66-8555-4fa6-80c1-90390e524b04",{"tags":32,"relatedLang":43,"relatedPosts":47},[33,35,37,39,41],{"name":17,"slug":34},"rust",{"name":21,"slug":36},"reqwest",{"name":19,"slug":38},"clap",{"name":20,"slug":40},"tokio",{"name":18,"slug":42},"cargo",{"id":15,"slug":44,"title":45,"language":46},"rust-cli-project-5-practical-steps-en","Rust CLI Project in 5 Practical Steps","en",[48,54,60,66,72,78],{"id":49,"slug":50,"title":51,"cover_image":52,"image_url":52,"created_at":53,"category":13},"8a892f4a-7b09-41e6-aca0-c1295694ae58","cursor-teams-pricing-adds-96-premium-seat-zh","Cursor Teams 加推 $96 Premium 座位","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1780909379891-7ue2.png","2026-06-08T09:02:25.073041+00:00",{"id":55,"slug":56,"title":57,"cover_image":58,"image_url":58,"created_at":59,"category":13},"aa52c4a3-9a96-402b-8153-e152f9fd96bc","awesome-ai-summerschool-ai-events-shortlist-zh","Awesome AI Summer School 變短名單","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1780905804300-zfvf.png","2026-06-08T08:02:46.455036+00:00",{"id":61,"slug":62,"title":63,"cover_image":64,"image_url":64,"created_at":65,"category":13},"2f526e1b-9aa1-4503-9927-31ce0009741c","rustup-rust-official-toolchain-installer-zh","Rustup 是 Rust 官方工具鏈安裝器","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1780903080771-8z56.png","2026-06-08T07:17:37.219276+00:00",{"id":67,"slug":68,"title":69,"cover_image":70,"image_url":70,"created_at":71,"category":13},"be87bcfd-1021-4d90-b766-2025d55b49e0","launch-site-rust-loot-routes-zh","Launch Site 讓你把撿資源變路線","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1780897701439-xowj.png","2026-06-08T05:47:49.787254+00:00",{"id":73,"slug":74,"title":75,"cover_image":76,"image_url":76,"created_at":77,"category":13},"4130de62-a037-464c-883d-5fbf8dd75789","open-source-rag-stack-build-plan-zh","開源 RAG 堆疊把混亂變計畫","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1780872500382-6ang.png","2026-06-07T22:47:55.345265+00:00",{"id":79,"slug":80,"title":81,"cover_image":82,"image_url":82,"created_at":83,"category":13},"4f0b90ab-f554-474e-9efd-ecec55257302","github-rag-production-list-battle-tested-tools-zh","GitHub 49 星 RAG 生產清單","https:\u002F\u002Fxxdpdyhzhpamafnrdkyq.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fcovers\u002Finline-1780870666920-t0hc.png","2026-06-07T22:17:20.22268+00:00",[85,90,95,100,105,110,115,120,125,130],{"id":86,"slug":87,"title":88,"created_at":89},"855cd52f-6fab-46cc-a7c1-42195e8a0de4","surepath-real-time-mcp-policy-controls-zh","SurePath 推出即時 MCP 政策控管","2026-03-26T07:57:40.77233+00:00",{"id":91,"slug":92,"title":93,"created_at":94},"9b19ab54-edef-4dbd-9ce4-a51e4bae4ebb","mcp-in-2026-the-ai-tool-layer-teams-use-zh","2026 年 MCP：團隊真的在用的 AI 工具層","2026-03-26T08:01:46.589694+00:00",{"id":96,"slug":97,"title":98,"created_at":99},"af9c46c3-7a28-410b-9f04-32b3de30a68c","prompting-in-2026-what-actually-works-zh","2026 提示工程，真正有用的是什麼","2026-03-26T08:08:12.453028+00:00",{"id":101,"slug":102,"title":103,"created_at":104},"05553086-6ed0-4758-81fd-6cab24b575e0","garry-tan-open-sources-claude-code-toolkit-zh","Garry Tan 開源 Claude Code 工具包","2026-03-26T08:26:20.068737+00:00",{"id":106,"slug":107,"title":108,"created_at":109},"042a73a2-18a2-433d-9e8f-9802b9559aac","github-ai-projects-to-watch-in-2026-zh","2026 必看 20 個 GitHub AI 專案","2026-03-26T08:28:09.619964+00:00",{"id":111,"slug":112,"title":113,"created_at":114},"a5f94120-ac0d-4483-9a8b-63590071ac6a","claude-code-vs-cursor-2026-zh","Claude Code 與 Cursor 深度對比：202…","2026-03-26T13:27:14.279193+00:00",{"id":116,"slug":117,"title":118,"created_at":119},"0975afa1-e0c7-4130-a20d-d890eaed995e","practical-github-guide-learning-ml-2026-zh","2026 機器學習入門 GitHub 實用指南","2026-03-27T01:16:49.712576+00:00",{"id":121,"slug":122,"title":123,"created_at":124},"bfdb467a-290f-4a80-b3a9-6f081afb6dff","aiml-2026-student-ai-ml-lab-repo-review-zh","AIML-2026：像課綱的學生實驗 Repo","2026-03-27T01:21:51.467798+00:00",{"id":126,"slug":127,"title":128,"created_at":129},"80cabc3e-09fc-4ff5-8f07-b8d68f5ae545","ai-trending-github-repos-and-research-feeds-zh","AI Trending：把 AI 資源收成一張表","2026-03-27T01:31:35.262183+00:00",{"id":131,"slug":132,"title":133,"created_at":134},"3ce6e6e2-bac5-463e-9f8d-45caabcc61f7","awesome-ai-for-science-research-tools-map-zh","AI 科研工具清單，開始像地圖了","2026-03-27T01:46:50.521945+00:00"]