GO數組解密:從基礎到高階全解

来源:https://www.cnblogs.com/xfuture/archive/2023/10/08/17748620.html
-Advertisement-
Play Games

在本文中,我們深入探討了Go語言中數組的各個方面。從基礎概念、常規操作,到高級技巧和特殊操作,我們通過清晰的解釋和具體的Go代碼示例為讀者提供了全面的指南。無論您是初學者還是經驗豐富的開發者,這篇文章都將助您更深入地理解和掌握Go數組的實際應用。 關註公眾號【TechLeadCloud】,分享互聯網 ...


在本文中,我們深入探討了Go語言中數組的各個方面。從基礎概念、常規操作,到高級技巧和特殊操作,我們通過清晰的解釋和具體的Go代碼示例為讀者提供了全面的指南。無論您是初學者還是經驗豐富的開發者,這篇文章都將助您更深入地理解和掌握Go數組的實際應用。

關註公眾號【TechLeadCloud】,分享互聯網架構、雲服務技術的全維度知識。作者擁有10+年互聯網服務架構、AI產品研發經驗、團隊管理經驗,同濟本復旦碩,復旦機器人智能實驗室成員,阿裡雲認證的資深架構師,項目管理專業人士,上億營收AI產品研發負責人。

file

1. 數組的基礎知識

在電腦科學中,數組是由同一類型的元素組成的數據結構,這些元素通過索引進行識別。Go語言中的數組是固定長度的,這與其他編程語言中可能會遇到的動態數組或列表是不同的。

1.1 定義與特點

在Go中,數組定義為具有固定長度和特定類型的元素的集合。它的長度是類型的一部分,這意味著[5]int[10]int是不同的類型。

示例:

var a [3]int  // 定義一個長度為3的int數組

這個數組有3個整數的位置,它們的預設值都是0。

1.2 數組的大小和類型

數組的大小必須在定義時確定,而且不能更改。這是Go數組與許多其他語言的動態數組或切片的主要區別。

示例:

var b [5]string  // 長度為5的字元串數組
b[2] = "hello"  // 設置第三個位置的值為"hello"

1.3 數組與切片的不同

數組和切片都可以存儲元素,但它們的行為是不同的。最大的區別是數組的大小是固定的,而切片的大小是動態的。

示例:

arr := [3]int{1, 2, 3}  // 一個固定長度的數組
sli := arr[:]  // 從數組創建一個切片

在上面的代碼中,我們首先定義了一個長度為3的數組arr,然後創建了一個新的切片sli,該切片引用arr的所有元素。

1.4 數組的值類型特性

在Go中,數組是值類型,而不是引用類型。這意味著當數組賦值給另一個數組時,內容會被覆制。任何在新數組上的更改都不會影響原始數組。

示例:

original := [3]int{1, 2, 3}
copy := original
copy[0] = 9

fmt.Println(original)  // 輸出:[1 2 3]
fmt.Println(copy)      // 輸出:[9 2 3]

在這個示例中,儘管我們更改了copy數組的第一個元素,但original數組的內容仍然保持不變。


2. 操作Go中的數組

在Go中,對數組的操作是直觀和簡單的,但理解其內部工作方式對於有效地利用數組很重要。

2.1 定義與初始化

Go允許多種方式來定義和初始化數組。

示例1:使用零值初始化

var arr [5]int

這將定義一個長度為5的整數數組,所有元素都被初始化為其零值,即0。

示例2:使用特定的值初始化

arr := [5]int{1, 2, 3, 4, 5}

這個示例中,數組在聲明的同時就被賦值了。

示例3:使用...來根據初始值的數量確定數組長度

arr := [...]int{1, 2, 3}

數組的長度在這裡是3,因為我們提供了三個初始化的值。

2.2 訪問和修改數組元素

數組元素可以通過索引進行訪問和修改,索引從0開始。

示例:

arr := [3]int{1, 2, 3}
fmt.Println(arr[1]) // 輸出: 2

arr[1] = 4
fmt.Println(arr[1]) // 輸出: 4

在上述代碼中,我們首先訪問了數組的第二個元素,然後修改了它的值。

2.3 遍曆數組

你可以使用for迴圈和range關鍵字來遍曆數組的每個元素。

示例:

arr := [3]string{"apple", "banana", "cherry"}

for index, value := range arr {
    fmt.Printf("Index %d has value: %s\n", index, value)
}

輸出:

Index 0 has value: apple
Index 1 has value: banana
Index 2 has value: cherry

2.4 使用內置函數len()獲取數組長度

如果你需要知道數組的長度,可以使用len()函數。

示例:

arr := [4]float64{3.14, 6.28, 9.42, 12.56}
fmt.Println(len(arr)) // 輸出: 4

這個示例輸出數組的長度,即4。


3. Go數組的高級用法

在瞭解了Go數組的基礎操作後,我們可以深入研究一些更高級的技巧和用法。

3.1 多維數組與嵌套數組

在Go中,你可以定義多維數組,最常見的是二維數組,例如,表示矩陣或表格。

示例:

// 定義一個2x3的整數二維數組
var matrix [2][3]int
matrix[0] = [3]int{1, 2, 3}
matrix[1] = [3]int{4, 5, 6}

fmt.Println(matrix[1][2])  // 輸出: 6

上述代碼初始化了一個2x3的矩陣,並輸出了第二行第三列的元素。

3.2 數組作為函數參數和返回值

由於數組是值類型,當數組作為函數參數傳遞時,它們會被覆制。你也可以使數組成為函數的返回值。

示例:

func sum(arr [3]int) int {
    total := 0
    for _, v := range arr {
        total += v
    }
    return total
}

arr := [3]int{10, 20, 30}
fmt.Println(sum(arr))  // 輸出: 60

上述函數計算三個整數數組的總和。

3.3 固定大小的數組和動態數組

Go的數組長度是固定的,但有時你可能不知道數組的確切大小。雖然這通常意味著你應該使用切片,但有時使用固定大小的數組作為底層結構可能更有意義。

示例:

func printFirstThree(arr [3]string) {
    fmt.Println(arr[0], arr[1], arr[2])
}

data := [...]string{"apple", "banana", "cherry", "date", "fig"}
printFirstThree([3]string{data[0], data[1], data[2]})  // 輸出: apple banana cherry

這個示例顯示瞭如何從更大的數組中選擇一個子集並將其傳遞給函數。

3.4 使用數組進行記憶體優化

由於Go的數組是連續的記憶體塊,它們對於需要緩存友好數據結構和記憶體緊湊的操作非常有用。

示例:

假設我們有一個表示3D點的結構,並且我們需要在一個大型數組中存儲這些點,使用數組而不是切片可以提供更好的性能。

type Point3D struct {
    x, y, z float64
}

var points [100000]Point3D  // 使用數組而不是切片來存儲大量數據

4. Go數組的特殊操作

Go的數組雖然在語言中是一個基本數據結構,但仍然有一些特殊的操作方法和技巧可以讓我們更有效地使用數組。

4.1 使用數組模擬其他數據結構

有時,為了優化性能或滿足特定需求,我們可能會使用數組模擬其他數據結構。

示例:模擬隊列

var queue [5]int
front, rear := -1, -1

func enqueue(x int) bool {
    if rear == len(queue)-1 {
        return false // 隊列滿
    }
    if front == -1 {
        front = 0
    }
    rear++
    queue[rear] = x
    return true
}

func dequeue() (int, bool) {
    if front == -1 {
        return 0, false // 隊列空
    }
    val := queue[front]
    front++
    if front > rear {
        front, rear = -1, -1
    }
    return val, true
}

enqueue(5)
enqueue(10)
v, ok := dequeue()
fmt.Println(v, ok) // 輸出: 5 true

上述代碼使用數組模擬了一個簡單的隊列。

4.2 比較兩個數組

在Go中,你可以使用==操作符直接比較兩個數組,前提是它們的類型和大小相同。

示例:

a := [3]int{1, 2, 3}
b := [3]int{1, 2, 3}
c := [3]int{1, 2, 4}

fmt.Println(a == b) // 輸出: true
fmt.Println(a == c) // 輸出: false

這裡,我們比較了兩個相同和一個不同的數組。

4.3 使用數組作為map的鍵

由於數組在Go中是可比較的,它們可以被用作map的鍵。

示例:

dict := map[[2]string]string{
    {"en", "hello"}: "你好",
    {"en", "world"}: "世界",
}

fmt.Println(dict[["en", "hello"]]) // 輸出: 你好

在此示例中,我們使用一個字元串數組作為map的鍵。

4.4 原地反轉數組

通過使用雙指針方法,我們可以在不使用額外空間的情況下原地反轉數組。

示例:

func reverse(arr *[5]int) {
    left, right := 0, len(*arr)-1
    for left < right {
        (*arr)[left], (*arr)[right] = (*arr)[right], (*arr)[left]
        left++
        right--
    }
}

data := [5]int{1, 2, 3, 4, 5}
reverse(&data)
fmt.Println(data)  // 輸出: [5 4 3 2 1]

關註公眾號【TechLeadCloud】,分享互聯網架構、雲服務技術的全維度知識。作者擁有10+年互聯網服務架構、AI產品研發經驗、團隊管理經驗,同濟本復旦碩,復旦機器人智能實驗室成員,阿裡雲認證的資深架構師,項目管理專業人士,上億營收AI產品研發負責人。

如有幫助,請多關註
TeahLead KrisChang,10+年的互聯網和人工智慧從業經驗,10年+技術和業務團隊管理經驗,同濟軟體工程本科,復旦工程管理碩士,阿裡雲認證雲服務資深架構師,上億營收AI產品業務負責人。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 正文 doCreateBean() 主要用於完成 bean 的創建和初始化工作,我們可以將其分為四個過程: 最全面的Java面試網站 createBeanInstance() 實例化 bean populateBean() 屬性填充 迴圈依賴的處理 initializeBean() 初始化 bean ...
  • 在讀《深入理解JVM虛擬機》這本書前兩章的時候整理了JDK從1.0到最新版本發展史,其中記錄了JDK這麼多年來演進過程中的一些趣聞及引人註目的一些特性,在調研JDK19新增特性的時候瞭解到了虛擬線程這個概念,於是對虛擬線程進行學習整理內容如下。 ...
  • Hadoop集群搭建 前期準備及JDK,hadoop安裝 設置主機名和添加主機映射 驗證連通性 SSH無密碼登錄 配置集群/分散式環境 修改workers 修改文件core-site.xml 修改hdfs-site.xml 修改mapred-site.xml 修改yarn-site.xml 分發到其 ...
  • 本節將向讀者介紹如何使用鍵盤滑鼠操控模擬技術,鍵盤滑鼠操控模擬技術是一種非常實用的技術,可以自動化執行一些重覆性的任務,提高工作效率,在Windows系統下,通過使用各種鍵盤滑鼠控制函數實現動態捕捉和模擬特定功能的操作。鍵盤滑鼠的模擬是實現自動化的必備流程,通常我們可以使用`keybd_event(... ...
  • 來源:juejin.cn/post/6886019929519177735 使用fluent mybatis可以不用寫具體的xml文件,通過java api可以構造出比較複雜的業務sql語句,做到代碼邏輯和sql邏輯的合一。不再需要在Dao中組裝查詢或更新操作,在xml或mapper中再組裝參數。那 ...
  • 寫在前面 Python是一種流行的高級編程語言,具有簡單易學、代碼可讀性高、應用廣泛等優勢。它是一種解釋型語言,可以直接在終端或集成開發環境(IDE)中運行,而無需事先編譯。 Python的安裝 Python的安裝過程非常簡單。首先,你可以從Python的官方網站(https://www.pytho ...
  • 當你有幾個技術博客平臺時,如何一鍵分發到多個技術博客平臺? 如果你寫博客,你一定會遇到這樣一個問題,我在掘金寫了一篇文章,想要發到其他的平臺每次都有複製粘貼,還經常遇到格式不匹配、圖片複製不過去等各種問題。可真是頭大呀 接下來就給你介紹一個非常王炸的工具,只要把你寫的文章編輯一次,就可以導出分發。 ...
  • 原文在這裡。 本教程為 Go 程式員提供了使用Protocol buffer的基本介紹。 本教程使用proto3向 Go 程式員介紹如何使用 protobuf。通過創建一個簡單的示例應用程式,它向你展示瞭如何: 在.proto中定義消息格式 使用protocol buffer編譯器 使用Go pro ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...