2012-04-12 12 views
5

मुझे एक चर को एक अज्ञात फ़ंक्शन में स्थानांतरित करने में समस्या हो रही है। क्या कोई समाधान है?जाओ: अज्ञात फ़ंक्शन में स्थानांतरण var

import "github.com/lxn/walk" 

*** 

var openAction [12]*walk.Action 
for i := 0; i < 12; i++ { 

    openBmp, err := walk.NewBitmapFromFile(_films[i][0]) 
    if err != nil { 
     log.Printf("Open bitmap for buildBody() :%v\n", err) 
    } 
    openAction[i] = walk.NewAction() 
    openAction[i].SetImage(openBmp) 
    openAction[i].SetText(_films[i][2]) 
    openAction[i].Triggered().Attach(func(){ 
     exec(i) 
    }) 
    mw.ToolBar().Actions().Add(openAction[i]) 
} 

कार्यकारी (i) जहां मैं हमेशा 11

+0

उत्तर में [एफएक्यू] (http://golang.org/doc/go_faq.html#closures_and_goroutines) में भी उत्तर दिया गया। – kostix

उत्तर

10
for i := 0; i < 12; i++ { 
    i := i 
    ... 

जैसा दिखता है उतना पागल, यह कुछ है जो आप गो कोड में देखेंगे। यह बंद होने के तरीके से और जिस तरह से चर स्केल किया जाता है, उससे परिणाम मिलता है। आपका अनाम कार्य एक बंद है जो मुझे कैप्चर करता है। विशेष रूप से, यह एक वैरिएबल को कैप्चर कर रहा है जिसे मैं नहीं कहता हूं, न कि वर्तमान मूल्य, और यह जो भी मैं गुंजाइश में रखता हूं उसे कैप्चर करता है। आपके मूल कोड में यह लूप वैरिएबल है, जो लूप के प्रत्येक पुनरावृत्ति के लिए एक ही चर है। आपके सभी बंद होने पर एक ही वैरिएबल पर कब्जा कर लिया गया। i := i के अतिरिक्त प्रत्येक पुनरावृत्ति पर एक नया चर घोषित करता है। अब प्रत्येक बंदरगाह इस नए चर को कैप्चर करेगा, और प्रत्येक पुनरावृत्ति पर यह एक अलग चर होगा।

थोड़ा और विस्तार से, लूप चर का दायरा मैं कथन के लिए है। इसमें लूप ब्लॉक शामिल है, लेकिन लूप वैरिएबल की घोषणा के बाद से मैं ब्लॉक के बाहर है, ब्लॉक के अंदर एक ही नाम के साथ एक नया वैरिएबल घोषित करना कानूनी है और ब्लॉक में उस बिंदु पर एक नया चर बनाता है। लूप वैरिएबल तब छायांकित होता है। अक्सर इस तरह घोषित एक वैरिएबल स्टैक पर जाता है, लेकिन इस मामले में कंपाइलर एस्केप विश्लेषण से पता चलता है कि ब्लॉक के अंत में जब यह बंद हो जाता है तो आपका बंदरगाह इस ब्लॉक वैरिएबल का जिक्र कर रहा है, और इसलिए चर ढेर। प्रत्येक पुनरावृत्ति पर, ब्लॉक को दोबारा लगाया जाता है और ढेर पर एक नया चर रखा जाता है।

+0

आसान लग रहा है और मुझे क्या चाहिए। – Vladislav

+0

वास्तव में एक साफ हैक है। मुझे उस चाल को याद रखना होगा। –

6

= मुझे लगता है कि यह आप क्या चाहते हैं आप मिल जाएगा:

openAction[i].Triggered().Attach(func(x int) func() { 
    return func() { exec(x) } 
}(i)) 

चाल आपके गुमनाम समारोह एक वापसी है अज्ञात फ़ंक्शन, और प्रत्येक निर्मित फ़ंक्शन i के प्रत्येक मान को संलग्न करेगा।

4

आप लूप के लिए जाने के लिए एक क्विर्क का सामना कर रहे हैं। लूप में i चर प्रत्येक पुनरावृत्ति के लिए एक नया चर नहीं है। इस वजह से आपके सभी बंद उसी वैरिएबल पर बंद हो रहे हैं जिसका मूल्य उनके नीचे बदल रहा है। जब आपका कोड लूप के बाद चलता है तो सभी कार्यों को बंद करने के लिए मूल्य 11 देखें।

समाधान मुझे एक फ़ंक्शन में पास करना है जो तब फ़ंक्शन तर्क पर बंद होने वाला एक और फ़ंक्शन देता है। यही कारण है कि एडम क्रॉसलैंड समाधान काम करता है।

संबंधित मुद्दे