2015-02-19 12 views
5

मैं जाओ चैनलों के साथ कोशिश कर रहा हूँ और यात्रा के दौरान ब्लॉग से समारोह उदाहरण नीचे के साथ भ्रमित:रिटर्निंग चैनल Golang

func gen(nums []int) <-chan int { 
out := make(chan int) 
go func() { 
    for _, n := range nums { 
     out <- n 
    } 
    close(out) 
}() 
fmt.Println("return statement is called ") 
return out 
} 

मुख्य:

func main() { 
c := make(<-chan int) 
c = gen([]int{2, 3, 4, 5}) 

// Consume the output.//Print 2,3,4,5 
fmt.Println(<-c) 
fmt.Println(<-c) 
fmt.Println(<-c) 
fmt.Println(<-c) 
} 

पूरा कोड: http://play.golang.org/p/Qh30wzo4m0

मेरे संदेह: 1. मेरी समझ थी, एक बार वापसी कहा जाता है फ़ंक्शन समाप्त कर दिया जाएगा और उस फ़ंक्शन के अंदर चैनल का कोई और जीवन नहीं होगा। यहां वापसी विवरण केवल कॉल किया जाता है एक बार। लेकिन आउट चैनल की सामग्री कई बार ली गई। इस मामले में निष्पादन का वास्तविक प्रवाह कैसा है? जब तक किसी को कहीं पढ़ता है कि चैनल (fmt.Println(<-c) कॉल)
(यह भी देखें "programming.Kindly मदद

उत्तर

4
out := make(chan int) 

यह एक बफ़र चैनल है, जो out <- nहोगा ब्लॉक का मतलब नहीं है मैं समवर्ती के लिए नया हूँ do golang channels maintain order ")

तो gen() समारोह के अंत में वापसी मतलब यह नहीं है शाब्दिक go func() समाप्त होता है (क्योंकि यह अभी भी पाठकों out चैनल की सामग्री का उपभोग करने के लिए इंतज़ार कर रहा है)।

लेकिन main समारोह gen() समारोह से लौटने के रूप में out चैनल हो रही।
gen() के बाद इसे प्राप्त करना संभव है?

तथ्य यह है कि gen() समाप्त अपने दिए गए मान पर कोई प्रभाव नहीं (out चैनल) है: "gen()" का लक्ष्य "उत्पन्न" करने के लिए कि out चैनल है।

maingen() समाप्त के बाद out उपयोग कर सकते हैं (gen() के दिए गए मान के रूप में) लंबा है।

gen() के भीतर शाब्दिक go func अभी भी चलता है, भले ही gen() समाप्त हो गया हो।

+0

, जल्दी reply.I के लिए धन्यवाद अपनी बात है, लेकिन बाहर चैनल जनरल की वापसी मान के माध्यम से मुख्य कार्य करने के लिए पारित हो जाता है() function.So जब जनरल() समाप्त होता है यह कैसे संभव है? –

+1

जीन समाप्त हो सकता है, लेकिन इसका आंतरिक शाब्दिक जाना func रहता है, एक स्वतंत्र goroutine के रूप में। – VonC

+0

मुख्य में परिवर्तनीय 'सी' जीन() फ़ंक्शन की वापसी है। तो आप जो कह रहे हैं वह है, जीन() के अंदर लाइव गो रूटीन के कारण जीन() समाप्त होने के बाद भी मूल्यों के साथ पॉप्युलेट किया जाएगा ... –

1

क्योंकि gen() चैनल जनसंख्या कार्य को गोरौटाइन के रूप में बंद कर देता है;

go func() { 
    for _, n := range nums { 
     out <- n 
    } 
    close(out) 
}() 

और यह ब्लॉक जब पहली मूल्य out चैनल पर भेज दिया जाता है, क्योंकि अभी तक कुछ नहीं प्राप्त कर रहा है (unbuffered चैनलों भेजने जब तक कुछ उन पर प्राप्त करता है पर ब्लॉक), कि goroutine अंत नहीं है जब gen() समारोह देता है।

main()

fmt.Println(<-c) 
... 

में c से प्राप्त करता है तो कारण goroutine gen() में शुरू किया चैनल को आबाद करने के रूप में रखने के लिए परिणाम तो अंत में main() रिटर्न पढ़ा रहे हैं, और जब goroutine रिटर्न, कुछ भी नहीं है क्योंकि वहाँ out पर भेजने के लिए छोड़ दिया गया, और c पर प्राप्त करने के लिए कुछ भी नहीं छोड़ा गया।

इसके अलावा, c := make(<-chan int)main() में gen() एक चैनल बनाता है और इसे वापस करता है।

देखें Playground

+0

@Internet मैं आपके बिंदु पर स्पष्ट हूं: "जीन() फ़ंक्शन लौटाता है जब गोरौटाइन समाप्त नहीं होता है।" लेकिन मुख्य समारोह जेन() फ़ंक्शन से वापस लौटने के रूप में चैनल प्राप्त कर रहा है। जेन() समाप्त होने के बाद इसे प्राप्त करना संभव है? यह मेरा संदेह है ... क्षमा करें अगर मैं बेवकूफ सवाल पूछ रहा हूं, तो मैं इसके लिए नया हूं ... –

+0

@faisalkk 'gen() 'फ़ंक्शन चैनल देता है, फिर समाप्त होता है। चैनल उस फ़ंक्शन द्वारा "स्वामित्व" नहीं है, यह अभी बनाया गया है और लौटाया गया है (चित्रण के लिए, गोरौटाइन को एक अलग "पृष्ठभूमि" फ़ंक्शन के रूप में देखा जा सकता है, जो 'जाने' कीवर्ड के उपयोग से "अस्वीकृत" है।) । उस बिंदु पर 'gen() 'फ़ंक्शन समाप्त होने के लिए स्वतंत्र है, और चैनल अन्य कार्यों द्वारा उपयोग किया जा सकता है। – Intermernet