Go 語言中的字符串

Go 語言中的字符串是 byte 值的序列。 如前所述,你可以使用下面的語法來定義一個字符串: var name = "test" 需要注意的是,和其他語言不同,字符串只能使用雙引號來定義,不能使用單引號。 要獲取字符串的長度,可以使用內建的 len() 函數: len(name) //4 你可以使用方括號來訪問字符串中的個別字符,通過傳遞所需字符的索引: name[0] //"t"(索引從 0 開始) name[1] //"e" 你可以使用以下語法獲取字符串的一部分: name[0:2] //"te" name[:2] //"te" name[2:] //"st" 使用這種方式,你可以創建字符串的副本: var newstring = name[:] 你可以將字符串分配給一個新變量: var first = "test" var second = first 字符串是不可變的,這意味著你不能更新字符串的值。 即使你使用賦值運算符將新值分配給 first,second 的值仍然是 "test": var first = "test" var second = first first = "another test" first //"another test" second //"test" 字符串是引用類型,這意味著如果你將一個字符串傳遞給一個函數,會複製字符串的引用,而不是它的值。但由於字符串是不可變的,在這種情況下與傳遞一個 int 沒有太大區別。 你可以使用 + 運算符來連接兩個字符串:...

go-github-api

#使用Go從GitHub獲取存儲庫列表 在這篇文章中,我將使用Go的net/http標準庫包,不使用任何附加庫,向GitHub API請求公共存儲庫的信息。 GitHub有一個很好的公共API稱為Search,您可以在https://developer.github.com/v3/search/#search-repositories上查看。 具體而言,我對獲取當前擁有1萬個以上星標的Go存儲庫感興趣。 我們可以傳遞一個查詢來獲取我們想要的內容。查看Search API文檔,我們需要對https://api.github.com/search/repositories進行HTTP GET請求,並傳遞查詢?q=stars:>=10000+language:go&sort=stars&order=desc:給我一個星標超過1萬個、使用Go語言的存儲庫,按星標數量進行排序。 最簡單的程式碼片段:我們使用net/http中的http.Get函數進行請求,並使用ioutil.ReadAll函數讀取返回的內容: package main import ( "io/ioutil" "log" "net/http" ) func main() { res, err := http.Get("https://api.github.com/search/repositories?q=stars:>=10000+language:go&sort=stars&order=desc") if err != nil { log.Fatal(err) } body, err := ioutil.ReadAll(res.Body) res.Body.Close() if err != nil { log.Fatal(err) } if res.StatusCode != 200 { log.Fatal("Unexpected status code", res.StatusCode) } log.Printf("Body: %s\n", body) } 就像您所看到的那樣,它並不易於閱讀。您可以將返回的內容使用在線格式化工具來理解實際結構。 現在讓我們處理JSON並從中生成一個漂亮的表格。 如果您對JSON主題還不熟悉,可以查看我有關使用Go處理JSON的初步指南[/go-json/]。 package main import ( "encoding/json" "fmt" "io/ioutil" "log" "net/http" "os" "text/tabwriter" "time" ) // Owner是存儲庫擁有者 type Owner struct { Login string } // Item是單個存儲庫的數據結構 type Item struct { ID int Name string FullName string `json:"full\_name"` Owner Owner Description string CreatedAt string `json:"created\_at"` StargazersCount int `json:"stargazers\_count"` } // JSONData包含GitHub API的響應 type JSONData struct { Count int `json:"total\_count"` Items []Item } func main() { res, err := http....

golang-slices

#Go中的切片 切片是一种类似于数组的数据结构,但其大小可变。 在底层,切片使用数组,并且它们是在数组之上构建的抽象,使它们更加灵活和有用(将数组视为较低级别)。 您将以与在高级语言中使用数组非常相似的方式使用切片。 您可以类似于数组定义一个切片,省略长度: var mySlice []string //字符串切片 您可以使用值初始化切片: var mySlice = []string{"First", "Second", "Third"} //或者 mySlice := []string{"First", "Second", "Third"} 您可以使用make()函数创建一个指定长度的空切片: mySlice := make([]string, 3) //长度为3的空字符串切片 您可以从现有切片创建一个新的切片,并向其附加一个或多个项目: mySlice := []string{"First", "Second", "Third"} newSlice := append(mySlice, "Fourth", "Fifth") 请注意,我们需要将append()的结果赋给一个新切片,否则会出现编译器错误。原始切片不会被修改,我们得到的是一个全新的切片。 您还可以使用copy()函数复制一个切片,使其不与其他切片共享内存,并且是独立的: mySlice := []string{"First", "Second", "Third"} newSlice := make([]string, 3) copy(newSlice, mySlice) 如果要复制到的切片没有足够的空间(比原始切片短),则仅复制第一个项目(直到有空间为止)。 您可以从数组初始化一个切片: myArray := [3]string{"First", "Second", "Third"} mySlice = myArray[:] 多个切片可以使用同一数组作为底层数组: myArray := [3]string{"First", "Second", "Third"} mySlice := myArray[:] mySlice2 := myArray[:] mySlice[0] = "test" fmt....

golang-variables-types

#Go中的變數和類型 在Go中,我們使用var來定義變數: var age = 20 變量可以在包層級進行定義: package main import "fmt" var age = 20 func main() { fmt.Println("Hello, World!") } 也可以在函數內進行定義: package main import "fmt" func main() { var age = 20 fmt.Println("Hello, World!") } 在包層級定義的變量在組成包的所有文件中都可見。一個包可以由多個文件組成,只需要創建另一個文件並在頂部使用相同的包名。 在函數層級定義的變量只在該函數內可見。當調用函數時,它被初始化,當函數結束執行時,它被銷毀。 在我們的示例中,我們使用: var age = 20 將值20分配給age。這使得Go確定變量age的類型為int。 我們稍後會見到更多關於類型的內容,但你應該知道有很多不同類型的數據類型,從int、string到bool。 我們還可以聲明一個沒有現有值的變量,但在這種情況下,我們必須像這樣設置類型: var age int var name string var done bool 當你知道值時,你通常會使用短變量聲明和:=運算符: age := 10 name := "Roger" 對於變量的名稱,你可以使用字母、數字和下劃線_,只要名稱以字母或下劃線開頭即可。 名稱是區分大小寫的。 如果名稱很長,通常使用駝峰命名法(camelCase),所以用於指示汽車名稱的名稱我們使用carName。 你可以使用賦值運算符=將新值賦給變量: var age int age = 10 age = 11 如果你有一個在程序中從不改變的變量,你可以使用const將其聲明為常量:...

Go工作空間介紹

Go的一個特點是我們稱之為工作空間。 工作空間是Go的“主體”。 默認情況下,Go選擇$HOME/go路徑,所以你會在家目錄中看到一個go文件夾。 它首次在安裝封包時創建(稍後我們將看到),也用於存儲一些工具。例如,當我在VS Code中加載hello.go文件時,它提示我安裝[gopls](https://pkg.go.dev/golang.org/x/tools/gopls)命令、Delve調試器(dlv)和[staticcheck linter](https://staticcheck.io/)。 它們被自動安裝在$HOME/go下: 當你使用go install安裝封包時,它們將存儲在這裡。這就是我們所謂的GOPATH。 你可以更改GOPATH環境變量以更改Go應該安裝封包的位置。 這在同時處理不同項目並希望隔離使用的庫時非常有用。

Go中的循環結構

Go中的循環結構 Go語言中最好的功能之一是為你提供更少的選擇。 我們只有一個循環語句:for。 我們可以像這樣使用它: for i := 0; i < 10; i++ { fmt.Println(i) } 我們首先初始化一個循環變量,然後設置我們每次迭代檢查的條件,以決定是否結束循環,最後在每次迭代結束時執行後置語句,在這個例子中是對i進行增量運算。 i++對變量i進行遞增。 < 運算符 用於比較i和數字10,返回true或false,決定是否執行循環主體。 與C或JavaScript等其他語言不同,我們不需要在這個區塊周圍加上括號。 其他語言提供了不同類型的循環結構,但Go只有這一種。如果你熟悉具有while循環結構的語言,我們可以像這樣模擬一個while循環: i := 0 for i < 10 { fmt.Println(i) i++ } 我們還可以完全省略條件,並在需要時使用break結束循環: i := 0 for { fmt.Println(i) if i < 10 { break } i++ } 我在循環主體內使用了一個if語句,但我們還沒有看到條件語句!我們將在下一節介紹它。 現在我要介紹的一個東西是range。 我們可以使用for來使用以下語法迭代一個數組: numbers := []int{1, 2, 3} for i, num := range numbers { fmt.Printf("%d: %d\n", i, num) } //0: 1 //1: 2 //2: 3 注意:我使用了fmt....

Go中的結構體

結構體是一種包含一個或多個變量的類型。它類似於一組變量,我們稱之為字段。這些字段可以具有不同的類型。 下面是一個結構體定義的示例: type Person struct { Name string Age int } 請注意,我們使用大寫字母命名字段,否則這些字段將對包私有。當您將結構體傳遞給其他包提供的函數(例如用於處理 JSON 或數據庫的函數)時,將無法訪問這些字段。 一旦我們定義了結構體,我們可以使用該類型初始化變量: flavio := Person{"Flavio", 39} 並且我們可以使用點語法訪問個別的字段: flavio.Age // 39 flavio.Name // "Flavio" 您還可以以以下方式從結構體初始化新變量: flavio := Person{Age: 39, Name: "Flavio"} 這使您只能初始化一個字段: flavio := Person{Age: 39} 或者甚至可以在不指定任何值的情況下初始化它: flavio := Person{} // 或者 var flavio Person 然後再設置其值: flavio.Name = "Flavio" flavio.Age = 39 結構體非常有用,因為您可以將不相關的數據進行分組,並將其傳遞給/從函數中,存儲在切片中等等。 定義後,結構體就像int或string一樣是一種類型,這意味著您還可以在其他結構體中使用它: type FullName struct { FirstName string LastName string } type Person struct { Name FullName Age int }

Go中的數組

數組是一系列相同類型的項目。 我們可以這樣定義一個數組: var myArray [3]string //一個包含3個字符串的數組 你可以通過以下方式初始化數組: var myArray = [3]string{"First", "Second", "Third"} 在這種情況下,你還可以讓Go為你計算項目的數量: var myArray = [...]string{"First", "Second", "Third"} 數組只能包含相同類型的值。 數組的大小是固定的,你必須明確定義數組的長度。這是數組的一部分的類型。同時,你不能使用變量來設置數組的長度。 由於這個限制,數組在Go中很少直接使用,而是使用切片(稍後會講到)。切片在內部使用數組,所以了解數組的工作原理還是必要的。 你可以使用方括號的表示法來訪問數組中的項目,這種表示法我們之前在字符串中已經使用過了,用來訪問單個字符: myArray[0] //索引從0開始 myArray[1] 你可以在數組的特定位置設置新的值: myArray[2] = "Another" 你可以使用len()函數獲取數組的長度: len(myArray) 數組是值類型。這意味著複製一個數組: anotherArray := myArray 或者把一個數組作為參數傳遞給函數,或者從函數中返回數組,都會創建原始數組的一個副本。 這與其他一些編程語言不同。 讓我們舉個簡單的例子,把一個新的值賦給數組中的一個項目。你會發現複製的數組並沒有改變: var myArray = [3]string{"First", "Second", "Third"} myArrayCopy := myArray myArray[2] = "Another" myArray[2] //"Another" myArrayCopy[2] //"Third" 請記住,你只能向數組添加一種類型的項目,例如設置myArray[2] = 2將引發錯誤。 在低層級上,元素在內存中連續存儲。

Go教程:由PostgreSQL支持的REST API

在本教程中,我將說明如何使用Go來提供一個JSON API。我將為Vue.js應用程序創建一個基本的後端,該後端將提供PostgreSQL數據庫中已有的數據。 我想要解決的問題的介紹 現有的數據庫結構 簡單的HTTP響應處理程序 連接到PostgreSQL 將處理程序移至它們自己的文件 實現/api/index端點 實現/api/repo/端點 這是正確的JSON嗎? 總結 正文 我想要解決的問題的介紹 我將在瀏覽器中使用Vue編寫一個單頁應用程序。這個應用程序將列出幾個Git存儲庫,並在點擊其中一個存儲庫時顯示我在其他地方擴充的一些詳細信息。 本文中要構建的API是只讀的(不會有POST請求)。 它將有2個端點: /api/index 將列出所有存儲庫 /api/repo/:owner/:name 將顯示由owner和name標識的存儲庫的詳細信息。 您可以將擁有者和名稱視為通常的github.comURL結構:github.com/owner/name。 我將把Go連接到一個現有的PostgreSQL數據庫,並根據請求中傳遞的參數提供響應。 現有的數據庫結構 該應用程序依賴於許多表。在此部分,我們將從數據庫中提取數據,並與以下 repositories:列出包含一些絕對數字(例如總點贊數)的存儲庫信息 repositories_weekly_data:以單週為單位存儲存儲庫中發生的情況,并聚合數字 repositories_historic_data:按月份聚合的提交和點贊信息 repositories_timelines:存儲與每個存儲庫相關的重要事件,例如達到 1 萬個點贊或首次創建的時間 簡單的HTTP響應處理程序 讓我們首先編寫一個簡單的HTTP服務器處理程序,用於處理2個路由: package main import ( "fmt" "log" "net/http" ) func main() { http.HandleFunc("/api/index", indexHandler) http.HandleFunc("/api/repo/", repoHandler) log.Fatal(http.ListenAndServe("localhost:8000", nil)) } func indexHandler(w http.ResponseWriter, r *http.Request) { //... } func repoHandler(w http.ResponseWriter, r *http.Request) { //... } 此代碼已經完成了對請求的並行處理。 連接到PostgreSQL 讓我們添加一個PostgreSQL連接。如果您對這些概念不熟悉,請查看這篇文章以了解如何在Go中使用SQL數據庫。 我不會使用任何ORM或外部庫,只使用純粹的database/sql代碼。...

Go程式語言介紹

這篇文章是關於Go語言的新系列開始。 Go是一種令人驚嘆、簡單、現代且快速的程式語言。 它是編譯型的、開源的、強類型的。 它是由Google工程師創建的,目標如下: 讓他們的專案編譯(和運行)更快 簡單易懂,人們可以在很短的時間內上手 具有足夠的低級功能,但也避免了一些過於低級的問題 可攜性強(編譯的Go程序是二進位文件,不需要其他文件來運行,並且跨平台,因此可以輕鬆分發) 乏味、穩定、可預測,提供少量犯錯的機會 方便利用多處理器系統的優點 它旨在成為C和C++的替代品。 此外,由於其兼容性特性,它可以與C和C++代碼庫一起使用。 Go可用於許多不同的需求,既可以解決簡單的需求,也可以解決非常複雜的需求。 您可以創建命令行工具、網路伺服器,並且在許多不同的情境中被廣泛使用。 Docker和Kubernetes都是使用Go編寫的。 我最喜歡的靜態網站生成器(Hugo)是用Go編寫的。 Caddy,一個相當流行的網頁伺服器,也是用Go編寫的。 有很多不同的常用工具在底層使用這個程式語言。 本手冊將向您介紹這個程式語言。 在我們深入研究語言的具體細節之前,以下是您應該知道的一些事項。 首先,https://go.dev是這個程式語言的主頁。這將成為您的首選資源: 從https://go.dev/doc/install下載Go二進制文件(go命令和其他相關工具) 參考官方Go文檔https://go.dev/doc/ 查看所有Go封包https://pkg.go.dev/ 訪問Go Playgroundhttps://go.dev/play/ …等等 前往https://go.dev/doc/install,並下載適合您操作系統的套件。 運行安裝程式,在流程結束時,您將在終端機中可以使用go命令: 打開終端機,運行go version,您應該看到類似於這樣的內容: 注意:在運行該程式之前,您可能需要打開一個新的終端機,因為安裝程式將Go二進制文件夾添加到了路徑中。 Go安裝文件的具體位置取決於您的操作系統。 在macOS中,它位於/usr/local/go,並且二進制文件位於/usr/local/go/bin。 在Windows上,它將位於C:\Program Files\go。 Windows和Mac的安裝程式將自動設置Go二進制文件路徑。 在macOS上,您還可以通過使用brew install golang通過Homebrew安裝Go。這樣將更容易進行後續的更新。 在Linux上,您需要在解壓縮Linux套件到/usr/local/go之後,將Go二進制文件夾添加到終端機路徑中,具體方法如下: echo 'export PATH=$PATH:/usr/local/go/bin' >> $HOME/.profile source $HOME/.profile 我推薦使用VS Code(又稱VS Code)作為您的編輯器。 閱讀有關**在VS Code中使用Go**的指南,快速進行“上手”設置。至少安裝Go擴展。 這個擴展將為您提供更簡單的生活,它提供IntelliSense(語法高亮顯示、自動完成、懸停提示、錯誤突出顯示…)和其他功能,如自動格式化、安裝封包的菜單選項、測試等等。 我建議您在VS Code設置中啟用“在保存時格式化”和“在粘貼時格式化”功能: 在Go中,注釋使用了通常的C/C++/JavaScript/Java語法: // 這是單行注釋 /* 多行 注釋 */ 該語言沒有語義上重要的空格。與C、C++、Rust、Java、JavaScript一樣,不同於Python,其中空格具有意義,用於創建塊而不是花括號。 分號是可選的,就像JavaScript一樣。而不像C、C++、Rust或Java。 Go對縮排和視覺順序非常重視。 當我們安裝Go時,還可以使用gofmt命令行工具來格式化Go程序。VS Code在幕後使用該工具來格式化Go源文件。 這非常有趣和創新,因為格式化和類似“應該將花括號放在循環定義的同一行還是下一行”的問題是一個巨大的浪費時間的問題。 語言創建者定義了規則,每個人都使用這些規則。...