क्या गो में एक फॉरेस्ट लूप है?


565

क्या foreachगो भाषा में एक निर्माण है? क्या मैं किसी स्लाइस या एरे का उपयोग कर सकता हूं for?


1
बाहर की जाँच करें: group.google.com/group/golang-nuts/browse_thread/thread/…
काकासी

1
गो ट्यूटोरियल के "एन इंटरल्यूड विद टाइप्स" सेक्शन (इसके अंत की ओर) rangeमें forछोरों के उपयोग का भी उल्लेख किया गया है।
कोस्टिक्स

जवाबों:


851

https://golang.org/ref/spec#For_range

एक "श्रेणी" खंड के साथ एक "बयान" के लिए एक सरणी, टुकड़ा, स्ट्रिंग या मानचित्र, या किसी चैनल पर प्राप्त मूल्यों की सभी प्रविष्टियों के माध्यम से पुनरावृत्त होता है। प्रत्येक प्रविष्टि के लिए यह पुनरावृत्ति मानों को पुनरावृत्ति मानों को निर्दिष्ट करता है और फिर ब्लॉक निष्पादित करता है।

उदहारण के लिए:

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
}

अंडरस्कोर, _, है खाली पहचानकर्ता , एक गुमनाम प्लेसहोल्डर।


7
इस उदाहरण में, तत्व elementका मूल्य है (एक प्रति) - यह स्वयं तत्व नहीं है। यद्यपि आप इसे असाइन कर सकते हैं element, लेकिन यह अंतर्निहित अनुक्रम को प्रभावित नहीं करेगा।
नोबार

मैं पायथन और सी में जानता हूं कि स्थानीयकरण (यानी गेटटेक्स्ट ) के लिए एक फ़ंक्शन के रूप में अंडरस्कोर का उपयोग करना अक्सर होता है । क्या अंडरस्कोर के उपयोग से गो में कोई समस्या होगी? क्या गो भी स्थानीयकरण के लिए एक ही पुस्तकालय का उपयोग करता है?
सेर्गेई कोलोडियाज़नी

2
@SergiyKolodyazhnyy Py डॉक्स कहते हैं "(गेटटेक्स्ट) फ़ंक्शन को आमतौर पर _()स्थानीय नामस्थान के रूप में अलियास किया जाता है" जो कि सिर्फ सम्मेलन द्वारा होता है , यह स्थानीयकरण के लिबास का हिस्सा नहीं है। अंडरस्कोर _एक वैध लेबल है, और यह गो (और पायथन और स्काला और अन्य लंग्स) में भी कन्वेंशन है जो _आपके द्वारा उपयोग नहीं किए जाने वाले रिटर्न वैल्यू के लिए असाइन किया जाएगा। _इस उदाहरण का दायरा forलूप के शरीर तक सीमित है । यदि आपके पास एक पैकेज-स्कॉप्ड फ़ंक्शन है, _तो यह लूप के दायरे के अंदर छाया होगा। स्थानीयकरण के लिए कुछ पैकेज हैं, मैंने _फ़ंक्शन नाम के रूप में कोई उपयोग नहीं देखा है ।
दावोस

149

गो ए है foreach सिंटैक्स है। यह सरणियों / स्लाइस, मानचित्र और चैनलों का समर्थन करता है।

सरणी या स्लाइस पर Iterate :

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

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

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

एक नक्शे पर Iterate :

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

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

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

एक चैनल पर Iterate :

for v := range theChan {}

एक चैनल पर इरेटिंग एक चैनल से प्राप्त करने के बराबर है जब तक कि यह बंद न हो:

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

10
हालाँकि, ओपी ने केवल स्लाइस के उपयोग के लिए कहा, मैं इस उत्तर को पसंद करता हूं, क्योंकि सबसे अंत में दूसरे उपयोगों की भी आवश्यकता होगी।
डोमोइरैगेटो

3
chanउपयोग के बारे में महत्वपूर्ण अंतर : यदि चैनल किसी बिंदु पर लेखक को बंद कर देता है, तो एक चैनल पर होने से वह लूप से बाहर निकल जाएगा। में for {v := <-theChan} बराबर है, यह होगा नहीं चैनल पास पर बाहर निकलें। आप दूसरे okरिटर्न वैल्यू के जरिए इसके लिए टेस्ट कर सकते हैं । TOUR EXAMPLE
colm.anseo

इसे पढ़ते समय एक ही सोचा, for { ... }एक अनंत लूप के लिए खड़ा है।
लेवीय

13

निम्न उदाहरण दिखाता है कि लूप को लागू करने के लिए rangeऑपरेटर को forलूप में कैसे उपयोग किया जाए 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 के खेल के मैदान में है

पुनश्च: यह भी दर्शाता है कि कोड की पठनीयता के लिए हैंगिंग ब्रेसेस एक बुरा विचार हैं। संकेत: कॉल forसे ठीक पहले स्थिति समाप्त हो जाती है action()। जाहिर है, है ना?


3
जोड़ें ,और यह स्पष्ट है कि forस्थिति कहाँ समाप्त होती है: play.golang.org/p/pcRg6WdxBd - यह वास्तव में पहली बार है जब मैंने go fmtशैली के लिए काउंटर तर्क पाया है , धन्यवाद!
टॉप

@topskip दोनों ही fmt मान्य हैं; बस सबसे अच्छा एक उठाओ :)
फिल्प हाग्लंड

@FilipHaglund यह बात नहीं है अगर यह वैध है। मुद्दा यह है कि आईएमओ यह स्पष्ट है कि ऊपर की स्थिति में उस स्थिति के लिए जहां स्थिति समाप्त होती है।
टॉपस्किप

8
मेरी राय में, यह उत्तर लक्षित प्रश्न के लिए अनुचित रूप से जटिल है।
एंड्रियाशेसिंग

@AndreasHassing अतिरेक को शुरू किए बिना कैसे करें?
ceving

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


3
यह जानना अच्छा है लेकिन यह ज्यादातर मामलों में उपयोगी नहीं है
श्रीधर

सहमत @ श्रीधर यह बहुत आला है।
रोबर्टबक

9

गोलांग में फोरच का उपयोग कैसे करें के लिए उदाहरण कोड निम्नलिखित है

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


बहुत अच्छी व्याख्या!
डर्लन डाइटरिच

4

हाँ, सीमा :

लूप के लिए रेंज का रूप एक स्लाइस या मैप पर घूमता है।

एक स्लाइस से अधिक होने पर, प्रत्येक पुनरावृत्ति के लिए दो मान दिए जाते हैं। पहला सूचकांक है, और दूसरा उस सूचकांक में तत्व की एक प्रति है।

उदाहरण :

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)
    }
}
  • आप _ को असाइन करके सूचकांक या मूल्य को छोड़ सकते हैं।
  • यदि आप केवल इंडेक्स चाहते हैं, तो ड्रॉप करें, मान पूरी तरह से।

1

यह स्पष्ट हो सकता है, लेकिन आप सरणी को इनलाइन इनलाइन कर सकते हैं:

package main

import (
    "fmt"
)

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

आउटपुट:

abc

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.