<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Rust 項(xiàng)目實(shí)戰(zhàn):從頭構(gòu)建一個(gè)筆記命令行程序(1)

          共 6446字,需瀏覽 13分鐘

           ·

          2022-02-10 22:28

          學(xué)習(xí)了 Rust 的語(yǔ)法后,我對(duì)這門語(yǔ)言感覺(jué)良好。于是計(jì)劃實(shí)戰(zhàn)一下。這篇文章是系列文章中的第一篇,該系列將介紹如何使用 Rust 構(gòu)建筆記應(yīng)用程序。

          最終目標(biāo)是為讀者提供足夠的知識(shí)來(lái)構(gòu)建自己的類似于 engram[1] 的筆記應(yīng)用程序。

          本系列內(nèi)容希望讀者具備一些編程知識(shí),但可能是 Rust 新手。該系列的每個(gè)部分都將產(chǎn)生一個(gè)功能性和有用的應(yīng)用程序,將在以后的文章中構(gòu)建。

          我強(qiáng)烈建議手動(dòng)敲入你看到的代碼,而不僅僅是復(fù)制和粘貼。這是獲得更好理解的最有效方法之一。

          01 入門

          從 Rust 官網(wǎng)找到入門頁(yè)面:https://www.rust-lang.org/learn/get-started,根據(jù)介紹安裝 Rust。

          安裝 Rust

          curl?--proto?'=https'?--tlsv1.2?-sSf?https://sh.rustup.rs?|?sh

          創(chuàng)建新的 Rust 項(xiàng)目

          cargo?new?notes

          cargo 是 Rust 包管理器[2]。它支持多種命令,本文將介紹其中的幾個(gè)。cargo new 在當(dāng)前目錄中創(chuàng)建一個(gè)名為 notes(或你指定的任何其他內(nèi)容)的新項(xiàng)目(和文件夾)。

          src/main.rs 包含一個(gè)簡(jiǎn)單的“Hello World”應(yīng)用程序。

          Cargo.toml 被稱為清單。請(qǐng)參閱 The Cargo Book[3] 以深入了解此處支持的內(nèi)容。我們只需要在這里做一個(gè)小的調(diào)整來(lái)添加一個(gè)依賴項(xiàng),所以不要太擔(dān)心現(xiàn)在不理解全部?jī)?nèi)容。

          默認(rèn)情況下,.gitignore 可以方便地從 git 中忽略目標(biāo)文件夾。

          運(yùn)行 hello world 應(yīng)用程序

          cargo?run

          cargo run[4] 命令構(gòu)建并運(yùn)行當(dāng)前的包。在本教程進(jìn)行更改后,你將使用它來(lái)運(yùn)行和測(cè)試這些更改。運(yùn)行一次后,你會(huì)看到更多的文件和文件夾出現(xiàn)。

          Cargo.lock 這是一個(gè)自動(dòng)生成的文件,它準(zhǔn)確指定了正在使用的庫(kù)的版本。有關(guān) Cargo.toml 與 Cargo.lock 的更多詳細(xì)信息,請(qǐng)參閱 Cargo Book[5]。

          target 這個(gè)文件夾是存儲(chǔ)所有構(gòu)建文件的地方。你幾乎可以忽略這一點(diǎn),因?yàn)?cargo 工具會(huì)根據(jù)需要處理它。

          在 VS Code 中打開(kāi)的默認(rèn) Rust 工作區(qū)

          02 準(zhǔn)備數(shù)據(jù)模型

          先從數(shù)據(jù)庫(kù)開(kāi)始。

          創(chuàng)建一個(gè) sqlite3 數(shù)據(jù)庫(kù)

          數(shù)據(jù)庫(kù)是幾乎所有應(yīng)用程序的核心。大多數(shù)新功能需要存儲(chǔ)一些新數(shù)據(jù)或以某種方式檢索現(xiàn)有信息。由于這些原因,這通常是你在構(gòu)建新事物時(shí)應(yīng)該考慮的第一件事。特別是,我試圖構(gòu)建的 “schema” 是什么。

          就本教程而言,我們的 schema 非常簡(jiǎn)單。我們想要一個(gè)帶有 id 列和 body 列的 notes 表。id 存儲(chǔ)特定筆記的唯一標(biāo)識(shí)符。這是大多數(shù)數(shù)據(jù)庫(kù)的必填字段,因?yàn)樗试S你直接引用現(xiàn)有項(xiàng)目。body 列將存儲(chǔ)我們正在保存的筆記的內(nèi)容。歡迎你在這里選擇其他一些你覺(jué)得更好的術(shù)語(yǔ)。一些可能的選擇:內(nèi)容、消息、文本或標(biāo)題。事后當(dāng)然可以改變這一點(diǎn),但隨著時(shí)間的推移,越來(lái)越多的代碼引用這些特定術(shù)語(yǔ),改變會(huì)越來(lái)越困難,所以試著選擇一個(gè)你能接受的并堅(jiān)持下去。

          我現(xiàn)在看到的大多數(shù)教程主要關(guān)注在服務(wù)器上存儲(chǔ)數(shù)據(jù)并通過(guò)某種 API 同步它。這個(gè)系列最終會(huì)那樣實(shí)現(xiàn),但像我們正在構(gòu)建的筆記應(yīng)用程序離線工作是非常重要的。盡早設(shè)置此限制允許我們考慮離線構(gòu)建——而不是試圖將其綁定到現(xiàn)有的云應(yīng)用程序。

          sqlite3[6] 是一個(gè)流行的數(shù)據(jù)庫(kù)庫(kù),它將數(shù)據(jù)庫(kù)存儲(chǔ)在文件系統(tǒng)上的單個(gè)文件中。這對(duì)用戶來(lái)說(shuō)很簡(jiǎn)單,因?yàn)樗麄儾恍枰\(yùn)行單獨(dú)的數(shù)據(jù)庫(kù)服務(wù)器,并且如果需要,數(shù)據(jù)庫(kù)文件可以傳遞到其他系統(tǒng)。

          創(chuàng)建筆記表

          第一步是創(chuàng)建一個(gè)表來(lái)存放我們的應(yīng)用程序數(shù)據(jù)。我們將使用 rusqlite 庫(kù)來(lái)處理我們與 sqlite 數(shù)據(jù)庫(kù)的連接。你可以通過(guò)修改 Cargo.toml 來(lái)安裝它。

          Cargo.toml

          [package]
          name = "notes"
          version = "0.1.0"
          edition = "2021"

          # See more keys and their definitions at [https://doc.rust-lang.org/cargo/reference/manifest.html](https://doc.rust-lang.org/cargo/reference/manifest.html "https://doc.rust-lang.org/cargo/reference/manifest.html")

          [dependencies.rusqlite]
          version = "0.26.1"
          features = ["bundled"]

          這會(huì)添加 rusqlite 作為依賴項(xiàng),下次嘗試構(gòu)建時(shí)將安裝該依賴項(xiàng)。features = ["bundled"] 告訴包編譯 SQLite 。這在 Windows 上特別有用,因?yàn)樵?Windows 中查找系統(tǒng)庫(kù)非常困難。

          添加后,你現(xiàn)在可以訪問(wèn) main.rs 中的 rusqlite,將現(xiàn)有代碼替換為以下內(nèi)容:

          use?rusqlite::{Connection,?Result};

          fn?main()?->?Result<(),?Box<dyn?std::error::Error>>?{
          ??let?conn?=?Connection::open("notes.db")?;
          ??conn.execute(
          ????"create?table?if?not?exists?notes?(
          ??????id?integer?primary?key,
          ??????body?text?not?null?unique
          ????)"
          ,
          ????[],
          ??)?;
          ??
          ??Ok(())
          }

          現(xiàn)在你可以運(yùn)行 cargo run ,一旦它構(gòu)建完成,notes 程序就會(huì)運(yùn)行并立即退出。然后,你應(yīng)該會(huì)在當(dāng)前目錄中看到一個(gè)名為 notes.db 的文件。如果你安裝了 DB 瀏覽器,你可以打開(kāi)這個(gè)文件并看到一個(gè)帶有 id 和 body 列的 notes 表。

          如果你再次運(yùn)行該程序,則不會(huì)發(fā)生任何事情。我們運(yùn)行的 SQL[7] 命令如下:

          create?table?if?not?exists?notes?(
          ??id?integer?primary?key,
          ??body?text?not?null?unique
          )

          指定僅在表不存在時(shí)創(chuàng)建表。當(dāng)我們用 let conn = Connection::open("notes.db")?; 打開(kāi)連接時(shí),我們將 rusqlite 庫(kù)指向同一個(gè)數(shù)據(jù)庫(kù)文件,它能夠確定該表已經(jīng)創(chuàng)建。

          可選的為 SQLite 安裝數(shù)據(jù)庫(kù)瀏覽器

          我發(fā)現(xiàn)能夠直觀地確認(rèn)事情按預(yù)期工作很有幫助。此時(shí),你可以下載一個(gè)數(shù)據(jù)庫(kù)瀏覽器,讓你可以查看新創(chuàng)建的 notes.db 文件的內(nèi)容。

          你可以下載 SQLite 的數(shù)據(jù)庫(kù)瀏覽器[8]。安裝后打開(kāi)它并單擊 Open Database 。

          notes.db 在 SQLite 的 DB Browser 中打開(kāi)

          現(xiàn)在我們已經(jīng)創(chuàng)建了一個(gè)表并設(shè)置了我們的 schema,我們可以繼續(xù)添加我們的第一條筆記。

          03 CRUD——?jiǎng)?chuàng)建、讀取、更新、刪除

          在任何程序中開(kāi)發(fā)新功能時(shí),我通常獨(dú)立處理 CRUD 首字母縮略詞的每個(gè)組件。對(duì)我來(lái)說(shuō)最有意義的構(gòu)建順序是:

          1. Create

          2. Read

          3. Delete

          4. Update

          本教程的這一部分將僅涵蓋 create。下篇文章將討論其他的。

          04 創(chuàng)建

          Create 是第一位的,因?yàn)闆](méi)有它,其他一切都沒(méi)有意義。在很多情況下,你的應(yīng)用程序只要可以創(chuàng)建就可以運(yùn)行。你顯然希望能夠完成其他工作,但他們的缺失不會(huì)影響你創(chuàng)建新項(xiàng)目。在我們的筆記示例中,你會(huì)看到,即使你剛剛添加了創(chuàng)建功能,你仍然擁有將筆記正確存儲(chǔ)到本地?cái)?shù)據(jù)庫(kù)的程序。如果這就是你能夠完成的全部工作,你仍然可以使用 DB Browser for SQLite 之類的工具打開(kāi) sqlite3 數(shù)據(jù)庫(kù)并在那里瀏覽所有筆記。

          在我們這里的小示例中,CRUD 的其余部分沒(méi)有太多內(nèi)容,但是在構(gòu)建更大的圖形用戶界面時(shí),僅演示和測(cè)試創(chuàng)建功能會(huì)很有用。

          要求

          對(duì)于筆記的創(chuàng)建,我只是希望能夠在終端中輸入我的筆記并按回車鍵。為了從命令行獲得輸入,我們將使用內(nèi)置的 std::io[9] 包。

          use?std::io;
          use?rusqlite::{Connection,?Result};

          fn?main()?->?Result<(),?Box<dyn?std::error::Error>>?{
          ??let?conn?=?Connection::open("notes.db")?;
          ??conn.execute(
          ????"create?table?if?not?exists?notes?(
          ??????id?integer?primary?key,
          ??????body?text?not?null?unique
          ????)"
          ,
          ????[],
          ??)?;

          ??let?mut?buffer?=?String::new();
          ??io::stdin().read_line(&mut?buffer)?;
          ??conn.execute("INSERT?INTO?notes?(body)?values?(?1)",?[buffer])?;

          ??Ok(())
          }

          我們可以再次使用 cargo run 運(yùn)行我們的應(yīng)用程序,你現(xiàn)在應(yīng)該看到它不會(huì)立即退出。你可以輸入任何你喜歡的消息,但 “hello world” 是標(biāo)準(zhǔn)的 “這東西工作正常嗎” 消息。按回車鍵后,程序應(yīng)該退出。

          提交第一個(gè)注釋后的示例輸出

          如果你在上面安裝了 DB Browser,你現(xiàn)在可以單擊 Browse Data,你將看到一行 id: 1 和 body: “hello world”(或你剛剛輸入的任何內(nèi)容)。

          DB 瀏覽器顯示“hello world”注釋

          這很好,但程序的目的是讓我們快速創(chuàng)建許多筆記。我們需要一些方法來(lái)使程序在提交第一個(gè)注釋后不會(huì)立即退出。

          為了實(shí)現(xiàn)這一點(diǎn),我們將使用一個(gè)循環(huán)——這里用一個(gè) while 循環(huán)。

          use?std::io;
          use?rusqlite::{Connection,?Result};

          fn?main()?->?Result<(),?Box<dyn?std::error::Error>>?{
          ??let?conn?=?Connection::open("notes.db")?;
          ??conn.execute(
          ????"create?table?if?not?exists?notes?(
          ??????id?integer?primary?key,
          ??????body?text?not?null?unique
          ????)"
          ,
          ????[],
          ??)?;

          ??let?mut?running?=?true;
          ??while?running?==?true?{
          ????let?mut?buffer?=?String::new();
          ????io::stdin().read_line(&mut?buffer)?;
          ????let?trimmed_body?=?buffer.trim();
          ????if?trimmed_body?==?""?{
          ??????running?=?false;
          ????}?else?{
          ??????conn.execute("INSERT?INTO?notes?(body)?values?(?1)",?[trimmed_body])?;
          ????}
          ??}

          ??Ok(())
          }

          為此,我們引入了一個(gè)名為 running 的布爾變量。當(dāng)我們啟動(dòng)程序時(shí),我們希望繼續(xù)接受輸入,因此我們將其初始化為 true。

          trimmed_body = buffer.trim(); 刪除輸入行末尾的任何空格。這是必要的,因?yàn)?read_line 返回帶有換行符 \n 的字符串。這在你可能會(huì)看到的大多數(shù)地方都是不可見(jiàn)的,但需要使 trimmed_body == "" 的相等檢查正確工作。作為一個(gè)額外的好處,.trim() 確保在我們存儲(chǔ)到數(shù)據(jù)庫(kù)之前刪除任何尾隨空格。

          我們現(xiàn)在可以再次運(yùn)行 cargo run,你現(xiàn)在應(yīng)該可以在不退出程序的情況下輸入一個(gè)又一個(gè)的字符。寫完筆記后,你可以在空行后再按 Enter 鍵(即按兩次 Enter 鍵),程序?qū)⑼顺觥?/p>

          單次運(yùn)行期間創(chuàng)建的多個(gè)筆記

          05 總結(jié)

          正如開(kāi)頭提到的,這篇文章是一個(gè)較長(zhǎng)系列的開(kāi)始,該系列將介紹如何使用 Rust 為命令行構(gòu)建和設(shè)計(jì)筆記應(yīng)用程序。在過(guò)去的一年里,我使用了一個(gè)簡(jiǎn)單的筆記應(yīng)用程序作為我用來(lái)試驗(yàn)新技術(shù)的項(xiàng)目。到目前為止,我已經(jīng)使用Swift iOS[10]、React Native for Android[11]、React[12] 和 Vanilla JavaScript 采用上述類似的方法構(gòu)建了筆記應(yīng)用程序(親切地稱為 engram[13])。

          我現(xiàn)在正在記錄這個(gè)過(guò)程,因?yàn)槭聦?shí)證明它非常成功地讓我了解我需要知道的東西。

          希望你通過(guò)本系列,自己動(dòng)手試驗(yàn),能夠?qū)?Rust 有更好的掌握。

          原文鏈接:https://devtails.xyz/how-to-build-a-note-taking-command-line-application-with-rust

          參考資料

          [1]

          engram: https://github.com/adamjberg/engram

          [2]

          cargo 是 Rust 包管理器: https://doc.rust-lang.org/cargo/

          [3]

          The Cargo Book: https://doc.rust-lang.org/cargo/reference/manifest.html

          [4]

          cargo run: https://doc.rust-lang.org/cargo/commands/cargo-run.html

          [5]

          請(qǐng)參閱 Cargo Book: https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html

          [6]

          sqlite3: https://www.sqlite.org/index.html

          [7]

          SQL: https://www.w3schools.com/sql/

          [8]

          下載 SQLite 的數(shù)據(jù)庫(kù)瀏覽器: https://sqlitebrowser.org/dl/

          [9]

          std::io: https://doc.rust-lang.org/std/io/index.html

          [10]

          Swift iOS: https://apps.apple.com/ca/app/engram/id1568952668

          [11]

          React Native for Android: https://play.google.com/store/apps/details?id=com.xyzdigital.engram

          [12]

          React: https://engram.xyzdigital.com/signup

          [13]

          engram: https://engramhq.xyz/




          往期推薦


          我是 polarisxu,北大碩士畢業(yè),曾在 360 等知名互聯(lián)網(wǎng)公司工作,10多年技術(shù)研發(fā)與架構(gòu)經(jīng)驗(yàn)!2012 年接觸 Go 語(yǔ)言并創(chuàng)建了 Go 語(yǔ)言中文網(wǎng)!著有《Go語(yǔ)言編程之旅》、開(kāi)源圖書《Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)》等。


          堅(jiān)持輸出技術(shù)(包括 Go、Rust 等技術(shù))、職場(chǎng)心得和創(chuàng)業(yè)感悟!歡迎關(guān)注「polarisxu」一起成長(zhǎng)!也歡迎加我微信好友交流:gopherstudio

          瀏覽 87
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产网址| 91香蕉在线观看 | 欧美性爱无码在线 | 在线天堂资源 | 色婷婷AV综合 |