2011-10-16 94 views
322

Go語言中是否存在foreach構造?我可以使用for迭代片或數組嗎?Go有沒有foreach循環?

+1

請查閱:http://groups.google。com/group/golang-nuts/browse_thread/thread/e2966ccdfe910e14?pli = 1 – Kakashi

+1

在for循環中'range'的使用也在Go教程的「An Interlude about Types」一節中提到。 – kostix

回答

512

http://golang.org/doc/go_spec.html#For_statements

A「爲」通過的所有條目的陣列,切片,字符串或地圖,或值的 一個信道上接收的語句與「範圍」的條款進行迭代。 對於每個條目,它將迭代值分配給對應的迭代變量 ,然後執行該塊。

舉個例子:

for index, element := range someSlice { 
    // index is the index where we are 
    // element is the element from someSlice for where we are 
} 

如果你不關心指數,你可以使用_

for _, element := range someSlice { 
    // element is the element from someSlice for where we are 
} 

下劃線,_,是blank identifier,匿名佔位符。

+8

可能有用的是說_被稱爲空白標識符,它只是忽略返回值 –

8

以下示例說明如何在for循環中使用range運算符來實現foreach循環。

func PrintXml (out io.Writer, value interface{}) error { 
    var data []byte 
    var err error 

    for _, action := range []func() { 
     func() { data, err = xml.MarshalIndent(value, "", " ") }, 
     func() { _, err = out.Write([]byte(xml.Header)) }, 
     func() { _, err = out.Write(data) }, 
     func() { _, err = out.Write([]byte("\n")) }} { 
     action(); 
     if err != nil { 
      return err 
     } 
    } 
    return nil; 
} 

該示例遍歷一個函數數組,以統一函數的錯誤處理。 Google的一個完整示例是playground。 PS:它也表明吊括號對於代碼的可讀性來說是一個壞主意。提示:for條件在action()呼叫之前結束。很明顯,不是嗎?

+3

添加''',並且'for'條件結束時更清楚:http://play.golang.org/p/ pcRg6WdxBd - 這實際上是我第一次找到'go fmt'風格的反指向,謝謝! – topskip

+0

@topskip都是有效的;只是選擇最好的一個:) –

+0

@FilipHaglund這是不是點,如果它是有效的。關鍵在於IMO在上述特定情況下for條件結束時更清楚。 – topskip

65

遍歷陣列切片

// index and value 
for i, v := range slice {} 

// index only 
for i := range slice {} 

// value only 
for _, v := range slice {} 

迭代一個地圖

// key and value 
for key, value := range theMap {} 

// key only 
for key := range theMap {} 

// value only 
for _, value := range theMap {} 

迭代一個通道

for v := range theChan {} 

等同於:通過使用for range對你的類型

for { 
    v := <-theChan 
} 
+4

雖然OP只要求切片用法,但我更喜歡這個答案,因爲大多數人最終還需要其他用法。 – domoarrigato

+1

關於'chan'用法的重要區別:如果作者在某個點關閉了頻道,則通道上的範圍將優雅地退出循環。在'for {v:= <-theChan}'_equivalent_中,它不會在通道關閉時退出。你可以通過第二個'ok'返回值來測試。 [TOUR示例](https://tour.golang.org/concurrency/4) – colminator

+0

在閱讀時認爲是相同的,對於{...}表示無限循環。 – Levit

6

你其實可以使用range沒有引用它的返回值:

arr := make([]uint8, 5) 
i,j := 0,0 
for range arr { 
    fmt.Println("Array Loop",i) 
    i++ 
} 

for range "bytes" { 
    fmt.Println("String Loop",j) 
    j++ 
} 

https://play.golang.org/p/XHrHLbJMEd

+2

很高興知道,但這在大多數情況下不會有用 – Sridhar

+0

同意@Sridhar它很適合。 – robstarbuck

3

以下是如何示例代碼在golang使用foreach

package main 

import (
    "fmt" 
) 

func main() { 

    arrayOne := [3]string{"Apple", "Mango", "Banana"} 

    for index,element := range arrayOne{ 

     fmt.Println(index) 
     fmt.Println(element)   

    } 

} 

這是一個運行示例https://play.golang.org/p/LXptmH4X_0