【go 】數組的多種初始化方式與操作

在 Go 語言中,數組是一種固定長度的數據結構,用于存儲相同類型的元素。以下是 Go 中數組的多種初始化方式,結合搜索結果整理如下:

(一)使用 var 關鍵字聲明并初始化數組

使用 var 關鍵字聲明數組時,可以指定數組的長度,數組的元素會被自動初始化為對應類型的零值。例如:

var arr [5]int // 聲明一個長度為5的整型數組,元素默認初始化為0

這種方式適用于需要明確數組長度且元素初始值為零值的場景。

(二)聲明時直接初始化數組

在聲明數組的同時,可以直接指定數組的元素值。例如:

var arr = [5]int{1, 2, 3, 4, 5} // 聲明并初始化一個長度為5的整型數組

這種方式適用于已知數組元素值的場景。

(三)使用短變量聲明初始化數組

通過短變量聲明 := 可以更簡潔地初始化數組。例如:

arr := [5]int{1, 2, 3, 4, 5} // 使用短變量聲明并初始化數組

這種方式適用于函數內部或需要快速聲明和初始化數組的場景。

(四)部分初始化數組

在初始化數組時,可以只指定部分元素的值,未指定的元素會被初始化為零值。例如:

arr := [5]int{1, 2} // 初始化前兩個元素為1和2,其余為0

這種方式適用于需要部分元素初始化的場景。

(五)使用 ... 自動推斷數組長度

在初始化數組時,可以使用 ... 讓編譯器根據初始化值的個數自動推斷數組長度。例如:

arr := [...]int{1, 2, 3, 4, 5} // 自動推斷數組長度為5

這種方式適用于數組長度由初始化值決定的場景。

(六)指定索引初始化數組

在初始化數組時,可以指定某些索引位置的值,未指定的索引位置會被初始化為零值。例如:

arr := [5]int{1: 10, 3: 30} // 初始化索引1為10,索引3為30,其余為0

這種方式適用于需要指定特定索引位置值的場景。

總結

Go 語言提供了多種數組的初始化方式,包括使用 var 關鍵字、短變量聲明、部分初始化、自動推斷長度以及指定索引初始化等。這些方式可以根據實際需求靈活選擇,以滿足不同場景下的使用需求。


數組元素操作

在 Go 語言中,數組是一種固定長度同類型的集合。我們可以對數組元素進行訪問、修改、遍歷、拷貝等操作。下面詳細介紹數組元素的常見操作方法。

一、聲明和初始化數組

1. 聲明數組

var arr [5]int // 聲明一個長度為 5 的 int 數組,默認值為 0

2. 初始化數組

arr := [3]int{1, 2, 3} // 聲明并初始化

也可以讓編譯器推斷長度:

arr := [...]int{1, 2, 3, 4} // 長度自動推斷為 4

二、訪問數組元素

通過索引訪問數組元素,索引從 0 開始:

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

?? 注意:索引超出范圍會導致 panic:

fmt.Println(arr[3]) // panic: index out of range [3] with length 3

三、修改數組元素

通過索引直接賦值即可修改元素:

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

四、遍歷數組元素

1. 使用 for 循環

for i := 0; i < len(arr); i++ {fmt.Println(arr[i])
}

2. 使用 range(推薦)

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

五、數組長度

使用 len() 獲取數組長度:

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

六、數組拷貝

Go 數組是值類型,賦值時會完整拷貝整個數組:

a := [3]int{1, 2, 3}
b := a
b[0] = 99
fmt.Println(a) // [1 2 3]
fmt.Println(b) // [99 2 3]

七、多維數組

Go 支持多維數組,例如二維數組:

var matrix [2][3]int
matrix[0] = [3]int{1, 2, 3}
matrix[1] = [3]int{4, 5, 6}
fmt.Println(matrix)
// 輸出: [[1 2 3] [4 5 6]]

八、數組 vs 切片(slice)

特性數組(Array)切片(Slice)
長度固定動態變化
傳遞方式值拷貝引用傳遞
聲明方式[n]T[]T
常用場景已知固定長度數據動態長度、靈活操作

九、示例代碼匯總

package main
import "fmt"
func main() {// 聲明并初始化arr := [3]int{10, 20, 30}// 訪問元素fmt.Println(arr[0]) // 10// 修改元素arr[1] = 99fmt.Println(arr) // [10 99 30]// 遍歷for i, v := range arr {fmt.Printf("index: %d, value: %d\n", i, v)}// 數組拷貝b := arrb[0] = 100fmt.Println(arr) // [10 99 30]fmt.Println(b)   // [100 99 30]
}

十、總結

  • Go 數組是固定長度、同類型的集合。
  • 通過索引訪問和修改元素。
  • 使用 range 遍歷數組更方便。
  • 數組是值類型,賦值或傳參時拷貝整個數組。
  • 如需動態長度,應使用切片(slice)。

存儲不同類型的元素

在 Go 語言中,數組(array)只能存儲相同類型的元素。這是 Go 類型系統的一個基本特性,它要求數組中的所有元素必須是同一類型,以確保類型安全和內存布局的一致性。


一、為什么數組不能存儲不同類型的元素?

Go 是靜態類型語言,數組的類型由其元素類型長度共同決定。例如:

var arr [3]int // 這是一個包含 3 個 int 類型元素的數組

如果你嘗試將不同類型的值放入數組,比如:

arr[0] = 10
arr[1] = "hello" // 編譯錯誤:cannot use "hello" (type untyped string) as type int

就會在編譯時報錯,因為類型不匹配。


二、如何實現存儲不同類型的數據?

雖然 Go 數組不能存儲不同類型,但你可以通過以下方式模擬存儲多種類型的數據:

1. 使用 interface{}(空接口)

interface{} 是 Go 中的萬能類型,可以表示任何類型。你可以聲明一個 []interface{} 類型的切片(slice)來存儲不同類型的值:

var data []interface{} = []interface{}{42,"hello",3.14,true,
}
for _, v := range data {fmt.Println(v)
}

注意:使用 interface{} 會失去類型安全,訪問時需要類型斷言(type assertion):

val := data[1].(string) // 斷言為 string 類型
fmt.Println(val)
2. 使用結構體(struct)

如果你希望更結構化地存儲不同類型的數據,可以定義一個結構體,將不同類型作為字段:

type Item struct {ID    intName  stringPrice float64
}
items := [2]Item{{1, "Apple", 2.5},{2, "Banana", 1.8},
}
3. 使用聯合體(C 風格)—— 不推薦

Go 沒有像 C 語言那樣的聯合體(union),也不鼓勵使用 unsafe 包來模擬,因為會破壞類型安全。

三、數組 vs 切片 vs 接口切片

類型是否可存多種類型特點
[n]T? 否固定長度,類型必須一致
[]T? 否動態長度,類型必須一致
[]interface{}? 是動態長度,可存任意類型

四、總結

  • Go 數組不能存儲不同類型,必須保持元素類型一致。
  • 若需存儲多種類型,推薦使用 []interface{} 或自定義結構體。
  • 使用 interface{} 時要注意類型斷言,避免運行時錯誤。

使用數組作為函數參數示例

在 Go 語言中,數組可以作為函數參數傳遞,但由于數組是值類型,這意味著傳遞時會復制整個數組,而不是傳遞引用。下面我們詳細講解如何使用數組作為函數參數,包括傳值、傳指針、以及一些注意事項。

一、傳值方式(默認行為)

1. 基本語法

當數組作為函數參數時,默認是值傳遞,即整個數組會被復制一份。

package main
import "fmt"
func modifyArray(arr [3]int) {arr[0] = 100fmt.Println("Inside function:", arr) // [100 2 3]
}
func main() {arr := [3]int{1, 2, 3}modifyArray(arr)fmt.Println("Outside function:", arr) // [1 2 3]
}

2. 特點

  • 函數內對數組的修改不會影響原數組。
  • 如果數組很大,復制整個數組會影響性能。

二、傳指針方式(避免復制)

1. 基本語法

為了避免復制整個數組,可以傳遞數組的指針:

package main
import "fmt"
func modifyArrayByPointer(arr *[3]int) {(*arr)[0] = 100fmt.Println("Inside function:", *arr) // [100 2 3]
}
func main() {arr := [3]int{1, 2, 3}modifyArrayByPointer(&arr)fmt.Println("Outside function:", arr) // [100 2 3]
}

2. 特點

  • 傳遞的是數組的指針,不會復制整個數組。
  • 函數內對數組的修改會影響原數組。
  • 適用于大數組,提升性能。

三、使用切片代替數組(推薦)

在 Go 中,更常見的做法是使用**切片(slice)**作為函數參數,因為切片是引用類型,傳遞的是底層數組的指針,不會復制整個數組。

1. 基本語法

package main
import "fmt"
func modifySlice(s []int) {s[0] = 100fmt.Println("Inside function:", s) // [100 2 3]
}
func main() {arr := [3]int{1, 2, 3}slice := arr[:] // 將數組轉換為切片modifySlice(slice)fmt.Println("Outside function:", arr) // [100 2 3]
}

2. 特點

  • 切片是引用類型,傳遞的是底層數組的指針。
  • 函數內對切片的修改會影響原數組。
  • 適用于動態長度的數據,更靈活。

四、多維數組作為參數

多維數組也可以作為函數參數,但需要明確指定每一維的長度(除了第一維)。

1. 基本語法

package main
import "fmt"
func printMatrix(matrix [3][2]int) {for i := 0; i < 3; i++ {for j := 0; j < 2; j++ {fmt.Printf("%d ", matrix[i][j])}fmt.Println()}
}
func main() {matrix := [3][2]int{{1, 2},{3, 4},{5, 6},}printMatrix(matrix)
}

2. 特點

  • 多維數組的長度必須嚴格匹配函數參數的聲明。
  • 如果長度不固定,建議使用切片的切片([][]int)。

五、總結

方式特點適用場景
傳值復制整個數組,函數內修改不影響原數組小數組,不希望原數組被修改
傳指針傳遞數組指針,函數內修改影響原數組大數組,避免復制
傳切片引用傳遞,函數內修改影響原數組動態長度數據,推薦使用
多維數組需明確指定長度,靈活性較低固定維度的矩陣數據

六、推薦做法

  1. 優先使用切片:除非明確需要固定長度的數組,否則推薦使用切片。
  2. 大數組傳指針:如果必須使用數組且數組較大,建議傳遞指針。
  3. 避免多維數組:如果維度不固定,建議使用切片的切片([][]int)。

數組進行排序

在 Go 語言中,可以使用標準庫中的 sort 包對數組進行排序。不過需要注意的是,Go 的 sort 包主要針對的是切片(slice),而不是數組(array)。因此,通常我們會先將數組轉換為切片,再進行排序操作。
下面我們詳細講解如何對數組進行排序,包括升序、降序、自定義排序等場景。

一、基本排序(升序)

1. 將數組轉為切片并排序

Go 的 sort.Intssort.Float64ssort.Strings 等函數只能對切片操作,因此我們需要先將數組轉為切片。

package main
import ("fmt""sort"
)
func main() {arr := [5]int{5, 2, 6, 3, 1}slice := arr[:] // 轉為切片sort.Ints(slice) // 升序排序fmt.Println("Sorted slice:", slice) // [1 2 3 5 6]fmt.Println("Original array:", arr) // [1 2 3 5 6]
}

注意:由于切片是對底層數組的引用,排序后原數組也會被修改。


二、降序排序

Go 的 sort 包沒有直接提供降序排序的函數,但可以使用 sort.Reverse 實現降序排序。

package main
import ("fmt""sort"
)
func main() {arr := [5]int{5, 2, 6, 3, 1}slice := arr[:]sort.Sort(sort.Reverse(sort.IntSlice(slice))) // 降序排序fmt.Println("Sorted slice (desc):", slice) // [6 5 3 2 1]
}

三、自定義排序

如果數組元素是結構體,或者需要按照自定義規則排序,可以實現 sort.Interface 接口。

1. 示例:按結構體字段排序

package main
import ("fmt""sort"
)
type Person struct {Name stringAge  int
}
type ByAge []Person
func (a ByAge) Len() int           { return len(a) }
func (a ByAge) Swap(i, j int)      { a[i], a[j] = a[j], a[i] }
func (a ByAge) Less(i, j int) bool { return a[i].Age < a[j].Age }
func main() {people := []Person{{"Alice", 30},{"Bob", 25},{"Charlie", 35},}sort.Sort(ByAge(people)) // 按 Age 升序排序fmt.Println("Sorted by age:", people)// Output: [{Bob 25} {Alice 30} {Charlie 35}]
}

四、穩定性排序

Go 的 sort 包提供了穩定排序 sort.Stable(),保證相等元素的相對順序不變。

package main
import ("fmt""sort"
)
func main() {arr := [5]int{5, 2, 6, 2, 1}slice := arr[:]sort.Stable(sort.IntSlice(slice)) // 穩定排序fmt.Println("Stable sorted slice:", slice) // [1 2 2 5 6]
}

五、總結

排序方式方法適用場景
升序排序sort.Ints() / sort.Float64s() / sort.Strings()基本類型排序
降序排序sort.Reverse(sort.IntSlice())需要降序時
自定義排序實現 sort.Interface結構體或復雜規則排序
穩定排序sort.Stable()需要保持相等元素順序

六、注意事項

  1. 數組 vs 切片:Go 的 sort 包主要針對切片,數組需要先轉為切片。
  2. 引用影響:切片排序會影響原數組,因為切片是對數組的引用。
  3. 性能考慮:對于大型數組,排序是 O(n log n) 的時間復雜度,合理使用。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/94394.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/94394.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/94394.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于Java+MySQL 實現(Web)網上商城

悅桔拉拉商城1. 課設目的可以鞏固自己之前所學的知識&#xff0c;以及學習更多的新知識。可以掌握業務流程&#xff0c;學習工作的流程。2. 開發環境硬件環境&#xff1a;Window11 電腦、Centos7.6 服務器軟件環境&#xff1a;IntelliJ IDEA 2021.1.3 開發工具JDK 16 運行環境M…

高并發搶單系統核心實現詳解:Redisson分布式鎖實戰

一、方法整體流程解析 #mermaid-svg-MROZ2xF7WaNPaztA {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-MROZ2xF7WaNPaztA .error-icon{fill:#552222;}#mermaid-svg-MROZ2xF7WaNPaztA .error-text{fill:#552222;strok…

Android12 User版本開啟adb root, adb remount, su, 關閉selinux

開啟adb root 直接看adb源碼&#xff1a; __android_log_is_debuggable就是判斷ro.debuggable屬性值&#xff0c;感興趣可以在 源碼下grep下實現看看。auth_required :在adb源碼下定義的全局變量&#xff0c;默認等于true,。看名字就是是否需要用戶授權的flag, 這里不再繼續跟…

金融專業高分簡歷撰寫指南

一、金融求職簡歷原則&#xff1a;深度與亮點并存在金融行業求職時&#xff0c;一份出色的簡歷需突出經歷深度與亮點。01 教育背景需如實填寫畢業院校、專業、GPA及所學課程。金融行業不少公司對求職者學校和學歷有嚴格標準&#xff0c;如“985”“211”院校或碩士以上學歷等。…

專題:2025生命科學與生物制藥全景報告:產業圖譜、投資方向及策略洞察|附130+份報告PDF、原數據表匯總下載

原文鏈接&#xff1a;https://tecdat.cn/?p43526 過去一年&#xff0c;全球生命科學VC融資回暖至1021.5億美元&#xff0c;并購交易雖下滑23%卻聚焦關鍵賽道&#xff0c;創新藥管線中GLP-1受體激動劑以170億美元市場規模領跑&#xff0c;AI技術將研發周期縮短60%……這些數據背…

Compose筆記(四十)--ClickableText

這一節主要了解一下Compose中的ClickableText&#xff0c;在Jetpack Compose中&#xff0c;ClickableText是用于創建可點擊文本的組件&#xff0c;其核心功能是通過聲明式語法將文本設置為交互式元素&#xff0c;用戶點擊時可觸發特定操作。簡單總結如下:API含義 text&#xff…

面試必刷的數組三連:原地刪除與合并

堅持用 清晰易懂的圖解 多語言代碼&#xff0c;讓每道題變得簡單&#xff01; 呆頭個人主頁詳情 呆頭個人Gitee代碼倉庫 呆頭詳細專欄系列 座右銘&#xff1a; “不患無位&#xff0c;患所以立。” 面試必刷的數組三連&#xff1a;原地刪除與合并前言目錄1.移除元素2.刪除有序…

力扣經典算法篇-41-旋轉圖像(輔助數組法,原地旋轉法)

1、題干 給定一個 n n 的二維矩陣 matrix 表示一個圖像。請你將圖像順時針旋轉 90 度。 你必須在 原地 旋轉圖像&#xff0c;這意味著你需要直接修改輸入的二維矩陣。請不要 使用另一個矩陣來旋轉圖像。 示例 1&#xff1a;輸入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]]…

譯|用戶增長策略如何使用因果機器學習的案例

來自上傳文件中的文章《[Causal Machine Learning for Growth: Loyalty Programs, LTV, and What to Do When You Can’t Experiment | by Torty Sivill | Towards AI]》 本文探討了當 A/B 測試不可行時&#xff0c;如何利用因果推斷從歷史數據中獲取洞察。技術亮點在于通過構建…

java~final關鍵字

final關鍵字final基本介紹final的使用細節final基本介紹 final是最終的意思&#xff0c;可以修飾類&#xff0c;屬性&#xff0c;方法&#xff0c;局部變量什么時候會要使用到final呢&#xff1f; 1.想要類不被繼承時 2.不希望類的某個屬性的值被改變時 3.不想父類的某個方法被…

Node.js(四)之數據庫與身份認證

數據庫與身份認證 目錄 數據庫與身份認證 十三、數據庫的基本概念 13.1 什么是數據庫 13.2 常見的數據庫及分類 13.3 傳統型數據庫的數據組織結構 1. Excel 的數據組織結構 2. 傳統型數據庫的數據組織結構 3. 實際開發中庫、表、行、字段的關系 十四、安裝并配置MySQ…

SpringBoot+SpringMVC常用注解

文章目錄發展歷程項目創建項目結構入門案例配置文件的兩種方式&#xff1a;只能使用一種創建項目二入門案例常用知識及注解Controller:類上面加&#xff0c;SpringMVC的注解GetMapping:方法上面加Spring框架的兩項核心功能Component:組件。控制反轉&#xff0c;加在業務類上面&…

標準GS相位恢復算法

標準GS相位恢復算法詳解與MATLAB實現 Gerchberg-Saxton (GS) 算法是一種經典的相位恢復方法&#xff0c;廣泛應用于光學成像、衍射成像和全息技術等領域。該算法通過迭代過程從未知相位的強度測量中恢復相位信息。 算法原理 GS算法的核心思想是利用傅里葉變換關系在空間域和頻率…

【Linux網絡編程基礎--socket地址API】

一、主機字節序和網絡字節序主機字節序&#xff08;Host Byte Order&#xff09;&#xff1a;你當前電腦的內存字節順序&#xff08;比如 x86 是小端&#xff09;網絡字節序&#xff08;Network Byte Order&#xff09;&#xff1a;統一規定為大端序&#xff08;高位字節在高位…

Linux路徑MTU發現(Path MTU Discovery, PMTU)

Linux路徑MTU發現&#xff08;Path MTU Discovery, PMTU&#xff09;機制是TCP/IP協議棧中確保數據包高效傳輸的核心技術。其核心目標是動態探測源主機到目的主機路徑上的最小MTU&#xff08;Maximum Transmission Unit&#xff09;&#xff0c;從而避免IP分片&#xff0c;提升…

【MySQL進階】------MySQL程序

MySQL程序簡介 MySQL安裝完成通常會包含如下程序&#xff1a; Linux系統程序?般在 /usr/bin?錄下&#xff0c;可以通過命令查看&#xff1a; windows系統?錄&#xff1a;你的安裝路徑\MySQL Server 8.0\bin&#xff0c;可以通過命令查看&#xff1a; 每個 MySQL 程序都有許…

Linux大頁內存導致服務內存不足

Linux大頁內存導致服務內存不足的解決方法 大頁內存&#xff08;Huge Pages&#xff09;是Linux內核提供的一種機制&#xff0c;用于減少TLB&#xff08;轉換后備緩沖區&#xff09;的壓力&#xff0c;提高內存訪問性能。然而&#xff0c;如果配置不當&#xff0c;大頁內存可能…

超寬帶測距+測角+無線通信一體化模組:智能門鎖、智能遙控器、AR頭戴、智能穿戴

超寬帶測距測角無線通信一體化模組&#xff1a;智能門鎖、智能遙控器、AR頭戴、智能穿戴UWB測距測角技術&#xff0c;因其高精度、低延遲、抗干擾能力&#xff0c;正廣泛應用于“人-物-設備”的空間感知場景&#xff0c;成為構建智能空間和精準互動的重要底層技術。代表廠商與產…

基于單片機空氣質量檢測/氣體檢測系統

傳送門 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品題目速選一覽表 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品題目功能速覽 概述 隨著環境污染問題日益嚴重&#xff0c;空氣質量監測成為社會關注的焦點。基于單片機的空氣質量檢…

網絡安全 | 從 0 到 1 了解 WAF:Web 應用防火墻到底是什么?

&#x1f914; 寫在前面 2020年 我參加公司的安全技能大賽&#xff0c;隊友在實操環節啟用了 WAF 防火墻&#xff0c;這是我第一次接觸到 Web 應用防火墻。作為一個 Web 開發老鳥&#xff0c;真是羞愧呀&#x1f602;。 &#x1f510; Web應用防火墻 WAF 全稱是 Web Applica…