首页 文章

Go中有一个foreach循环吗?

提问于
浏览
416

Go语言中是否有 foreach 结构?我可以使用 for 迭代切片或数组吗?

7 回答

  • 645

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

    带有“range”子句的“for”语句遍历数组,切片,字符串或映射的所有条目,或者在通道上接收的值 . 对于每个条目,它将迭代值分配给相应的迭代变量,然后执行该块 .

    举个例子:

    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,一个匿名占位符 .

  • 99

    迭代 arrayslice

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

    迭代 map

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

    迭代 channel

    for v := range theChan {}
    

    迭代通道相当于从通道接收直到它关闭:

    for {
        v, ok := <-theChan
        if !ok {
            break
        }
    }
    
  • 2

    以下示例说明如何在 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() 调用之前结束 . 很明显,不是吗?

  • 10

    事实上,您可以使用 range 而不使用 for 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

  • 7

    以下是如何在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

  • 0

    是的, Range

    for循环的范围形式在切片或映射上迭代 .

    在切片上进行测距时,每次迭代都会返回两个值 . 第一个是索引,第二个是该索引处元素的副本 .

    示例:

    package main
    
    import "fmt"
    
    var pow = []int{1, 2, 4, 8, 16, 32, 64, 128}
    
    func main() {
        for i, v := range pow {
            fmt.Printf("2**%d = %d\n", i, v)
        }
    
        for i := range pow {
            pow[i] = 1 << uint(i) // == 2**i
        }
        for _, value := range pow {
            fmt.Printf("%d\n", value)
        }
    }
    
    • 您可以通过分配_来跳过索引或值 .

    • 如果您只想要索引,请完全删除值 .

  • 10

    这可能是显而易见的,但您可以像这样内联数组:

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        for _, element := range [3]string{"a", "b", "c"} {
            fmt.Print(element)
        }
    }
    

    输出:

    abc
    

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

相关问题