2012-05-01 29 views
6

से इसे वापस करने के विरुद्ध एक पैरामीटर पास कर रहा है क्योंकि यह शीर्षक से स्पष्ट हो सकता है कि हमें किस दृष्टिकोण को प्राथमिकता देना चाहिए?फ़ंक्शन

इरादा कुछ विधि मानकों को पारित करना और आउटपुट के रूप में कुछ प्राप्त करना है। हम एक और पैरामीटर पास कर सकते हैं और विधि इसे अपडेट कर देगी और विधि को अब कुछ भी वापस नहीं करने की आवश्यकता है, विधि केवल आउटपुट वैरिएबल अपडेट करेगी और यह कॉलर पर दिखाई देगी।

मैं इस उदाहरण के माध्यम से प्रश्न को फ्रेम करने की कोशिश कर रहा हूं।

List<String> result = new ArrayList<String>(); 

for (int i = 0; i < SOME_NUMBER_N; i++) { 
    fun(SOME_COLLECTION.get(i), result); 
} 

// in some other class 
public void fun(String s, List<String> result) { 
    // populates result 
} 

बनाम

List<String> result = new ArrayList<String>(); 

for (int i = 0; i < SOME_NUMBER_N; i++) { 
    List<String> subResult = fun(SOME_COLLECTION.get(i)); 
    // merges subResult into result 
    mergeLists(result, subResult); 
} 

// in some other class 
public List<String> fun(String s) { 
    List<String> res = new ArrayList<String>(); 
    // some processing to populate res 
    return res; 
} 

मैं समझता हूँ कि एक संदर्भ से गुजरता है और एक और नहीं करता है।

हमें कौन सा (विभिन्न परिस्थितियों में) पसंद करना चाहिए और क्यों?

अद्यतन: इसे केवल परिवर्तनीय वस्तुओं के लिए विचार करें।

+0

मुझे यकीन नहीं है कि आप क्या पूछ रहे हैं। क्या आप पूछ रहे हैं कि आपको कौन सी परिस्थितियों को एक चर के पास प्राप्त करने के लिए विधि के भीतर प्राप्त करना चाहिए, जिसमें getArg() या जिसे भी कॉल किया जा सकता है? – Charles

+0

नहीं, आप इसे गलत समझ रहे हैं या मैं व्यक्त नहीं कर सका। मैं पूछ रहा हूं: क्या हमें एक चर के रूप में किसी फ़ंक्शन को एक चर के रूप में पास करना चाहिए या इसे फ़ंक्शन से वापस करना चाहिए? किन स्थितियों में हमें इनमें से किसी एक का उपयोग करना चाहिए? आशा है, मैं स्पष्ट हूँ! – instanceOfObject

उत्तर

14

फ़ंक्शन से मूल्य लौटने आमतौर पर कोड लिखने का एक क्लीनर तरीका है।पॉइंटर्स बनाने और नष्ट करने की प्रकृति के कारण मूल्य को पास करना और इसे संशोधित करना सी/सी ++ शैली है।

डेवलपर्स आम तौर पर उम्मीद नहीं है कि उनके मूल्यों, एक समारोह के माध्यम से इसे पारित द्वारा संशोधित किया जाएगा जब तक कि समारोह स्पष्ट रूप से इसे मूल्य को संशोधित करता है कहा गया है (और हम अक्सर वैसे भी प्रलेखन स्किम)।

हालांकि अपवाद हैं।

Collections.sort का उदाहरण है, जो वास्तव में एक सूची के स्थान पर तरह में एक क्या करता है पर विचार करें। कल्पना करें कि 1 मिलियन आइटम की एक सूची है और आप इसे सॉर्ट कर रहे हैं। शायद आप एक दूसरी सूची नहीं बनाना चाहते हैं जिसमें एक और 1 मिलियन प्रविष्टियां हों (भले ही ये प्रविष्टियां मूल पर वापस आ रही हों)।

यह अपरिवर्तनीय वस्तुओं के पक्ष में भी अच्छा अभ्यास है। अपरिवर्तनीय वस्तुएं विकास के अधिकांश पहलुओं (जैसे थ्रेडिंग) में बहुत कम समस्याएं पैदा करती हैं। तो एक नई वस्तु लौटकर, आप पैरामीटर को परिवर्तनीय होने के लिए मजबूर नहीं कर रहे हैं।

महत्वपूर्ण हिस्सा विधियों में आपके इरादों के बारे में स्पष्ट होना है। मेरी सिफारिश है कि जब संभव हो तो पैरामीटर को संशोधित करने से बचें क्योंकि यह जावा में सबसे आम व्यवहार नहीं है।

+0

समझ में आता है! धन्यवाद! – instanceOfObject

0

इसे लौटने से यह आपके कोड क्लीनर को बनाए रखेगा और विधियों/वर्गों के बीच कम युग्मन होगा।

0

यह सर्वोत्तम प्रथाओं और कार्यक्रम के लिए आपकी अपनी विधि के बारे में अधिक है। मैं कहता हूँ यदि आप जानते हैं कि यह एक एक मूल्य की तरह वापसी प्रकार समारोह होने जा रहा है होगा:

समारोह IsThisNumberAPrimeNumber {}

तो आप जानते हैं कि यह केवल कभी एक बूलियन वापस जाने के लिए जा रहा है। मैं आम तौर पर सहायक अनुप्रयोगों के रूप में कार्यों का उपयोग करता हूं और बड़ी उप प्रक्रियाओं के रूप में नहीं। मैं नामकरण सम्मेलनों को भी लागू करता हूं जो उप-कार्य वापस आने की अपेक्षा करते हैं। उदाहरण:

GetUserDetailsRecords GetUsersEmailAddress IsEmailRegistered

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

0

कारण मुझे नहीं लगता कि हम समझते हैं कि ये दो अलग-अलग प्रकार के कार्य हैं। फ़ंक्शन में एक चर को पास करना फ़ंक्शन डेटा देने का माध्यम है। फ़ंक्शन से इसे वापस करना फ़ंक्शन से डेटा पास करने का एक तरीका है।

आप इन दो कार्यों के बीच अंतर का अर्थ है:

public void doStuff(int change) { 
    change = change * 2; 
} 

और

public void doStuff() { 
    int change = changeStorage.acquireChange(); 
    change = change * 2; 
} 

फिर पीछे नहीं है आम तौर पर क्लीनर, लेकिन वहाँ कई कारणों से (सुरक्षा, समारोह visibilty, आदि) हैं कि इस तरह से डेटा पारित करने से आपको रोक सकता है।

यह भी बेहतर है क्योंकि यह कोड को फिर से उपयोग करने में आसान बनाता है, साथ ही इसे अधिक मॉड्यूलर बनाता है।

6

आप इसे वापस आ जाएगी। आपके द्वारा प्रदान किया गया दूसरा उदाहरण जाने का तरीका है।

सबसे पहले, अपने को और अधिक स्पष्ट। जब अन्य लोग आपका कोड पढ़ते हैं, तो कोई गॉचा नहीं है कि वे नोटिस नहीं कर सकते कि पैरामीटर को आउटपुट के रूप में संशोधित किया जा रहा है। आप चर नाम देने का प्रयास कर सकते हैं, लेकिन जब कोड पठनीयता की बात आती है, तो यह बेहतर होता है।

बिग कारण आपको इसे पारित करने के बजाय इसे क्यों वापस करना चाहिए, अपरिवर्तनीय वस्तुओं के साथ है। आपका उदाहरण, सूची, उत्परिवर्तनीय है, इसलिए यह ठीक काम करता है। लेकिन यदि आप उस स्ट्रिंग का उपयोग करने की कोशिश कर रहे थे, तो यह काम नहीं करेगा। यदि आप एक पैरामीटर के रूप में एक स्ट्रिंग पारित

तार के रूप में, अपरिवर्तनीय हैं, और फिर समारोह कहने के लिए थे:

public void fun(String result){ 
    result = "new string"; 
} 

कि आप में पारित परिणाम का मूल्य बदला जा नहीं होगा। इसके बजाए, स्थानीय स्कोप चर 'परिणाम' अब मज़ा के अंदर एक नई स्ट्रिंग को इंगित करता है, लेकिन परिणामस्वरूप आपकी कॉलिंग विधि मूल स्ट्रिंग को इंगित करती है।

यदि आप कहा जाता है:

String test = "test"; 
fun(test); 
System.out.println(test); 

यह प्रिंट होगा: "परीक्षण", नहीं "नया स्ट्रिंग"!

तो निश्चित रूप से, यह वापसी से बेहतर है। :)

+0

यूप! मैं समझता हूं, सवाल केवल म्यूटेबल वस्तुओं के लिए था! उत्तर बीटीडब्ल्यू के लिए धन्यवाद! – instanceOfObject

+0

कोई समस्या नहीं है। हाँ, म्यूटेबल ऑब्जेक्ट्स के लिए यह काम करता है, और कुछ मामलों में यह बेहतर होगा (आप टुपल का उपयोग किये बिना कई ऑब्जेक्ट्स नहीं लौट सकते हैं) लेकिन आम तौर पर यदि यह सब वही होता है, तो वापसी बेहतर कोड शैली होती है। – SpacePrez