में लूप वैरिएबल पर बंद होने पर एरिक लिपर्ट के ब्लॉग पोस्ट Closing over the loop variable considered harmful में चर्चा की गई, सी # में लूप वैरिएबल पर बंद होने से अप्रत्याशित परिणाम हो सकते हैं। मैं समझने की कोशिश कर रहा था कि क्या "गेटचा" Scala पर लागू होता है।स्कैला
सभी कीसबसे पहले, के बाद से यह एक स्काला सवाल यह है कि, मैं एरिक Lippert के सी # उदाहरण अपने कोड
// Create a list of integers
var values = new List<int>() { 100, 110, 120 };
// Create a mutable, empty list of functions that take no input and return an int
var funcs = new List<Func<int>>();
// For each integer in the list of integers we're trying
// to add a function to the list of functions
// that takes no input and returns that integer
// (actually that's not what we're doing and there's the gotcha).
foreach(var v in values)
funcs.Add(()=>v);
// Apply the functions in the list and print the returned integers.
foreach(var f in funcs)
Console.WriteLine(f());
अधिकांश लोगों को इस कार्यक्रम में 100, 110, 120 मुद्रित करने के लिए उम्मीद की कुछ टिप्पणियां जोड़ने समझा कोशिश करता हूँ । यह वास्तव में 120 प्रिंट, 120, 120 के मुद्दा () => v
समारोह हम funcs
सूची में जोड़ने के वी चर, नहीं वी के मूल्य पर बंद है। जैसा कि वी बदलता है, पहले लूप में, हम तीनों बंदरगाहों को funcs
सूची में जोड़ते हैं, वही वैरिएबल बनाम "देखें", (जब तक हम उन्हें दूसरे लूप में लागू करते हैं) उनमें से सभी के लिए मूल्य 120 है।
मैं स्काला के उदाहरण कोड का अनुवाद करने की कोशिश की है:
import collection.mutable.Buffer
val values = List(100, 110, 120)
val funcs = Buffer[() => Int]()
for(v <- values) funcs += (() => v)
funcs foreach (f => println(f()))
// prints 100 110 120
// so Scala can close on the loop variable with no issue, or can it?
स्काला वास्तव में एक ही मुद्दा से ग्रस्त नहीं है या मैं सिर्फ एरिक Lippert के कोड बुरी तरह से अनुवाद किया है और यह पुन: पेश करने में विफल रहा है?
इस व्यवहार ने कई बहादुर सी # डेवलपर को तोड़ दिया है, इसलिए मैं यह सुनिश्चित करना चाहता था कि स्कैला के साथ कोई अजीब समान गठिया न हो। लेकिन, एक बार जब आप समझते हैं कि सी # जिस तरह से करता है, एरिक लिपर्ट के उदाहरण कोड के प्रकार का अर्थ समझ में आता है (यह मूल रूप से काम बंद करने का तरीका है): तो स्कैला अलग-अलग क्या कर रही है?
'v' स्कैला कोड में एक परिवर्तनीय चर नहीं है। ध्यान रखें कि 'लूप्स के लिए 'समझ' _not_' हैं। स्कैला कोड वास्तव में मानक 'फॉर' लूप की तुलना में प्रकृति में कहीं अधिक कार्यात्मक रूप से अनुवाद करता है, इसलिए, जहां आपके पास सी # कोड में कई मानों के साथ एक 'v' था, आपके पास एकाधिक' v 'है कि प्रत्येक को अपना एकल मूल्य मिलता है स्कैला कोड में। – Destin
@ डेस्टिन: धन्यवाद, आपको इसे एक उत्तर के रूप में पोस्ट करना चाहिए था। मैं कम से कम इसे ऊपर उठाया होगा। (आप अभी भी इसे कर सकते हैं, वास्तव में) –