Go 語言 range 關鍵字全面解析

Go 語言 range 關鍵字全面解析

range 是 Go 語言中用于迭代數據結構的關鍵字,支持多種數據類型的遍歷操作。它提供了一種簡潔、安全且高效的方式來處理集合類型的數據。

基本語法

for index, value := range collection {// 循環體
}

1. 數組/切片迭代

fruits := []string{"Apple", "Banana", "Cherry"}// 只獲取索引
for i := range fruits {fmt.Printf("Index: %d\n", i)
}// 只獲取值
for _, fruit := range fruits {fmt.Printf("Fruit: %s\n", fruit)
}// 獲取索引和值
for i, fruit := range fruits {fmt.Printf("%d: %s\n", i, fruit)
}

??輸出??:

Index: 0
Index: 1
Index: 2
Fruit: Apple
Fruit: Banana
Fruit: Cherry
0: Apple
1: Banana
2: Cherry

2. 映射(Map)迭代

ages := map[string]int{"Alice": 25,"Bob":   30,"Eve":   28,
}// 迭代鍵值對
for name, age := range ages {fmt.Printf("%s is %d years old\n", name, age)
}// 只迭代鍵
for name := range ages {fmt.Println("Name:", name)
}// 只迭代值
for _, age := range ages {fmt.Println("Age:", age)
}

??注意??:映射的迭代順序是不確定的,每次運行可能不同

3. 字符串迭代

str := "Go語言"// 按字節迭代(可能不完整處理Unicode字符)
for i, char := range []byte(str) {fmt.Printf("Byte %d: %d\n", i, char)
}// 正確方式:按Rune迭代(處理完整Unicode字符)
for i, char := range str {fmt.Printf("Rune %d: %c (Unicode: U+%04X)\n", i, char, char)
}// 統計字符串的Unicode字符數量
count := 0
for range str {count++
}
fmt.Printf("'%s' has %d runes\n", str, count) // "Go語言" has 4 runes

??輸出??:

Rune 0: G (Unicode: U+0047)
Rune 1: o (Unicode: U+006F)
Rune 2: 語 (Unicode: U+8BED)
Rune 5: 言 (Unicode: U+8A00)

4. 通道(Channel)迭代

func producer(ch chan<- int) {for i := 0; i < 3; i++ {ch <- i * 10}close(ch)
}func main() {ch := make(chan int, 3)go producer(ch)// 通道迭代直到關閉for value := range ch {fmt.Println("Received:", value)}
}

??輸出??:

Received: 0
Received: 10
Received: 20

5. 特殊數據結構迭代

a. 自定義類型迭代器

type IntRange struct {start, end int
}func (r *IntRange) Next() (int, bool) {if r.start >= r.end {return 0, false}value := r.startr.start++return value, true
}func (r *IntRange) Iterate() chan int {ch := make(chan int)go func() {defer close(ch)for value, ok := r.Next(); ok; value, ok = r.Next() {ch <- value}}()return ch
}func main() {r := &IntRange{start: 5, end: 8}for n := range r.Iterate() {fmt.Println(n) // 輸出: 5,6,7}
}

b. 迭代空集合

var empty []int
for i, v := range empty {fmt.Println("This won't run")
}
// 安全,不會出錯

6. 底層原理分析

range 實際上是一種語法糖,編譯時會轉換為普通循環:

// 原始代碼
for i, v := range slice {// 操作
}// 編譯后等效的代碼
{tmpslice := slicefor i := 0; i < len(tmpslice); i++ {v := tmpslice[i]// 操作}
}

重要注意事項:

  1. ??值復制??:range 迭代返回的是集合元素的??副本??,修改副本不影響原數據(指針/引用類型除外)
  2. ??指針處理??:
    type Point struct{ X, Y int }points := []Point{{1, 2}, {3, 4}}for i, p := range points {// 修改副本不會影響原始數據p.X++ points[i].Y++ // 正確修改原數據的方式
    }

7. 性能優化技巧

a. 避免值復制

// 對于大結構體,避免復制開銷
type BigStruct struct { data [1024]byte }bigSlice := make([]BigStruct, 1000)// 較差的方式:每次迭代復制整個結構體
for _, item := range bigSlice {// item 是副本
}// 推薦方式:按索引訪問
for i := range bigSlice {// 直接操作 bigSlice[i]bigSlice[i].data[0] = 1
}

b. 避免內存分配

// 預分配切片用于結果收集
var results []int
data := []int{1, 2, 3, 4, 5}// 預分配空間
results = make([]int, 0, len(data))
for _, v := range data {results = append(results, v*2)
}

8. 常見問題與解決方案

問題1:修改原始切片失敗

nums := []int{1, 2, 3}
for _, num := range nums {num *= 2 // 無效修改
}

??解決方案??:使用索引

for i := range nums {nums[i] *= 2
}

問題2:goroutine 使用閉包陷阱

for i, v := range []int{10, 20, 30} {go func() {fmt.Println(i, v) // 所有goroutine輸出相同的值}()
}

??解決方案??:通過參數傳遞值

for i, v := range []int{10, 20, 30} {go func(i, v int) {fmt.Println(i, v) // 正確輸出}(i, v)
}

9. 不同數據類型的特性總結

數據類型返回參數順序保證修改影響
??數組??(index, value)順序(0→N)副本修改無效
??切片??(index, value)順序(0→N)副本修改無效
??映射??(key, value)隨機副本修改無效
??字符串??(index, rune)順序(0→N)不可修改
??通道??(value)發送順序N/A

實際應用案例

1. 并行處理切片

func parallelProcess(data []int) []int {results := make([]int, len(data))var wg sync.WaitGroupwg.Add(len(data))for i, v := range data {go func(i, v int) {defer wg.Done()// 執行耗時操作results[i] = v * v}(i, v)}wg.Wait()return results
}

2. 并發安全迭代器

func safeIterate(m map[string]int) {// 創建臨時副本迭代keys := make([]string, 0, len(m))for k := range m {keys = append(keys, k)}for _, k := range keys {v := m[k] // 安全訪問// 處理邏輯}
}

3. 大型文件處理

func processLargeFile(filename string) {file, err := os.Open(filename)if err != nil {log.Fatal(err)}defer file.Close()scanner := bufio.NewScanner(file)for scanner.Scan() {line := scanner.Text()// 逐行處理大文件processLine(line)}if err := scanner.Err(); err != nil {log.Fatal(err)}
}

總結

Go 的 range 關鍵字是處理集合類數據的核心工具:

  1. ??簡潔性??:簡化循環語法
  2. ??安全性??:正確處理不同類型的邊界情況
  3. ??高效性??:編譯優化后性能優秀
  4. ??靈活性??:支持多數據類型和值選擇

關鍵使用要點:

  • 理解不同數據類型的迭代特性
  • 注意值復制行為(尤其是大型結構體)
  • 在并發環境中安全使用
  • 利用索引優化性能

掌握 range 的深度使用可以極大提高 Go 編程的效率和代碼質量。

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

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

相關文章

美化顯示LLDB調試的數據結構

前面的博文美化顯示GDB調試的數據結構介紹了如何美化顯示GDB中調試的數據結構&#xff0c;本文將還是以mupdf庫為例介紹如何美化顯示LLDB中調試的數據結構。 先看一下美化后的效果&#xff1a; 一、加載自定義腳本 與GDB類似&#xff0c;需要添加一個~/.lldbinit文件&#xf…

【Java學習筆記】日期類

日期類 第一代日期類&#xff1a;Date 引入包 import java.text.ParseException&#xff1a;日期轉換可能會拋出轉換異常 import java.text.SimpleDateFormat import java.util.Date 1. 基本介紹 Date&#xff1a;精確到毫秒&#xff0c;代表特定的瞬間 SimpleDateForma…

C++基礎進階:函數、內聯函數與Lambda函數詳解

引言 在C編程的旅程中&#xff0c;函數是構建復雜程序的基本單元。它們像樂高積木一樣&#xff0c;允許我們將代碼分解成更小、更易于管理的部分。今天&#xff0c;我們將深入探討C中的三種重要函數類型&#xff1a;普通函數、內聯函數以及Lambda函數。掌握它們&#xff0c;將…

從Node.js到React/Vue3:流式輸出技術的全棧實現指南

本文將從底層原理到工程實踐&#xff0c;完整解析如何使用Node.js后端結合React和Vue3前端實現流式輸出功能&#xff0c;涵蓋協議選擇、性能優化、錯誤處理等關鍵細節&#xff0c;并通過真實場景案例演示完整開發流程。 一、流式輸出的核心原理與協議選擇 1.1 流式傳輸的底層機…

AT2401C中科微2.4g芯片PA

作為無線通信系統的核心模塊&#xff0c;射頻前端芯片通過整合功率放大器&#xff08;PA&#xff09;、濾波器、開關和低噪聲放大器&#xff08;LNA&#xff09;等關鍵組件&#xff0c;成為保障通信質量、降低功耗及維持信號穩定的決定性因素。 AT2401C是一款面向2.4GHz無線通信…

Linux安裝jdk、tomcat

1、安裝jdk sudo yum install -y java-1.8.0-openjdk-devel碰到的問題&#xff1a;/var/run/yum.pid 已被鎖定 Another app is currently holding the yum lock&#xff1b; waiting for it to exit… https://blog.csdn.net/u013669912/article/details/131259156 參考&#…

在本地電腦中部署阿里 Qwen3 大模型及連接到 Elasticsearch

在今天的文章中&#xff0c;我將參考文章 “使用 Elastic 和 LM Studio 的 Herding Llama 3.1” 來部署 Qwen3 大模型。據測評&#xff0c;這是一個非常不錯的大模型。我們今天嘗試使用 LM Studio 來對它進行部署&#xff0c;并詳細描述如何結合 Elasticsearch 來對它進行使用。…

【設計模式】2.策略模式

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 商場收銀軟件為例 1. 基礎版 total 0def click_ok(price,num):tot price * numtotal totprint(合計&#xff1a;, total)增加打折 total 0def cli…

c++中的輸入輸出流(標準IO,文件IO,字符串IO)

目錄 &#xff08;1&#xff09;I/O概述 I/O分類 不同I/O的繼承關系 不同I/O對應的頭文件 &#xff08;2&#xff09;iostream 標準I/O流 iostream頭文件中的IO流對象 iostream頭文件中重載了<<和>> 緩沖區示意圖 標準輸入流 cin用法 cin&#xff1a;按空…

人工智能學習06-循環

人工智能學習概述—快手視頻 人工智能學習06-循環—快手視頻

【電路】阻抗匹配

&#x1f4dd; 阻抗匹配 一、什么是阻抗匹配&#xff1f; 阻抗匹配&#xff08;Impedance Matching&#xff09;是指在電子系統中&#xff0c;為了實現最大功率傳輸或最小信號反射&#xff0c;使信號源、傳輸線與負載之間的阻抗達到一種“匹配”狀態的技術。 研究對象&#x…

【vue】Uniapp 打包Android 文件選擇上傳問題詳解~

需求 uniapp兼容android app&#xff0c;pc&#xff0c;h5的文件選擇并上傳功能。 需要支持拍照和相冊選擇&#xff0c;以及選擇其他類型文件上傳~ 實踐過程和問題 開始使用uni-file-picker組件 以為很順利&#xff0c;android模擬器測試…… 忽略了平臺兼容性提示~&#…

Python:操作 Excel 格式化

??Python 操作 Excel 格式化完整指南(openpyxl 與 xlsxwriter 雙方案) 在數據處理和報表自動化中,Python 是一把利器,尤其是配合 Excel 文件的讀寫與格式化處理。本篇將詳細介紹兩大主流庫: openpyxl:適合讀取與修改現有 Excel 文件xlsxwriter:適合創建新文件并進行復…

Prompt Enginering(提示工程)先進技術

前沿 CoT&#xff08;Chain-of-Thought&#xff09;和 ReACT&#xff08;Reasoning and Acting&#xff09;是兩種先進的 Prompt Engineering&#xff08;提示工程&#xff09; 技術&#xff0c;旨在提升大語言模型&#xff08;LLM&#xff09;的推理、規劃和執行能力。 CoT&a…

【C++系列】模板類型特例化

1. C模板類型特例化介紹 ??定義??&#xff1a;模板類型特例化&#xff08;Template Specialization&#xff09;是C中為模板的特定類型提供定制實現的機制&#xff0c;允許開發者對通用模板無法處理的特殊類型進行優化或特殊處理。 ??產生標準??&#xff1a; C98/03…

AI數據分析在體育中的應用:技術與實踐

在現代體育競技領域&#xff0c;"數據驅動"已不再是一個遙遠的概念。尤其隨著人工智能&#xff08;AI&#xff09;和大數據分析的不斷成熟&#xff0c;從職業俱樂部到賽事直播平臺&#xff0c;從運動員訓練到球迷觀賽體驗&#xff0c;AI正以前所未有的方式滲透并改變…

計數思想-眾數

11203-眾數 題目描述(Description) 眾數是指在一組數據中&#xff0c;出現次數最多的數。例如&#xff1a;1, 1, 3 中出現次數最多的數為 1&#xff0c;則眾數為 1。 給定一組數&#xff0c;你能求出眾數嗎&#xff1f; 輸入格式(Format Input) 第 1 行輸入一個整數 n (1 &…

【Go語言基礎【20】】Go的包與工程

文章目錄 零、概述一、包基礎1、包的核心作用2、包的聲明與結構2.1、 包聲明&#xff08;Package Declaration&#xff09;2.2、 包的目錄結構&#xff08;工程視角&#xff09; 3、包的導入與調用3.1、導入包&#xff08;Import Packages&#xff09;3.2、 調用包成員3.3、 導…

《C++初階之入門基礎》【命名空間 + 輸入輸出 + 缺省參數 + 函數重載】

【命名空間 輸入&輸出 缺省參數 函數重載】目錄 前言&#xff1a;---------------hello world---------------比較C語言和C的第一個程序&#xff1a;hello word ---------------命名空間---------------什么是命名空間&#xff1f;怎么使用命名空間&#xff1f;怎么定義…

java綜合項目開發一課一得

文章目錄 Java 綜合項目課程學習&#xff1a;探索與成長之路一、課程初體驗&#xff1a;從理論走向實踐&#xff08;一&#xff09;系統學習 Java 核心理論知識&#xff08;二&#xff09;開啟首個實踐項目 —— 圖書管理系統 二、項目攻堅&#xff1a;挑戰與突破&#xff08;一…