2009-04-09 11 views
12

बनाम को देखते हुए एक समारोह की तरह:nargin अस्तित्व

function foo(myParam) 
if nargin<1 
    myParam = 'default value'; 
end % if 
end % function 

मैंने देखा है लोगों nargin संस्करण

if ~exist('myParam', 'var') 
    myParam = 'default value'; 
end %if 

मैं सोच रहा हूँ के स्थान पर निम्नलिखित अगर वहाँ किसी भी तरह कुछ का उपयोग वरीयता किसी भी तरह से?

"~ मौजूद ..." मेरे लिए संस्करण लाभ यह है कि अगर मैं अपने समारोह मापदंडों का क्रम बदल तो यह अभी भी काम करना चाहिए है। हालांकि इस दृष्टिकोण के साथ मेरी चिंता यह है कि मैं अनजाने में वेरिएबल्स को चुन सकता हूं जो विश्व स्तर पर परिभाषित किए गए हैं या नेस्टेड फ़ंक्शंस के मामले में आसपास के फ़ंक्शन के दायरे में हैं।

इस मुद्दे पर कोई विचार?

उत्तर

10

दोनों को काम करना चाहिए। लेकिन ...

अस्तित्व धीमा हो जाता है, क्योंकि इसे प्रश्न में चर के लिए अपने कार्यक्षेत्र को देखना चाहिए। जब आप इस तरह की त्रुटि जांच लिखते हैं, तो आप नहीं चाहते हैं कि वे CPU चक्रों को चूस लें। नर्गिन के खिलाफ परीक्षण एक संख्यात्मक मूल्य के खिलाफ एक सरल परीक्षण है।

मैं आमतौर पर एक और व्यापक परीक्षण का सुझाव देता हूं। जैसे

if (nargin<1) || isempty(myparam) 

    myparam = defaultvalue; 

elseif 

    ... 

end 

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

7

मैं दो कारणों के लिए nargin साथ जाना होगा: यदि आप अपने कार्य करने के लिए मापदंडों के आदेश को बदलते हैं, इनपुट की जाँच कोड अपनी समस्याओं का कम से कम होने जा रहा है ऊपर फिक्सिंग

  1. ; आपको अपने कॉल में सभी कॉल साइट्स को भी अपडेट करना होगा।

  2. nargin दूर सस्ता है। अस्तित्व में है, भले ही वेरिएबल्स की जांच करने के लिए स्कॉप्ड किया गया हो, फिर भी पूरे वर्कस्पेस को स्ट्रिंग तुलनाओं के समूह के साथ स्कैन करना होगा। नर्गिन विधि में ऑपरेशन से कम एक स्केलर होता है।

4

मैं हमेशा nargchk का उपयोग करके तर्कों को मान्य करता हूं, और उसके बाद nargin परीक्षणों के साथ उनके पास जाता हूं। जैसा कि अन्य ने बताया, वे सस्ता हैं, और मुझे लगता है कि स्पष्ट है।

उन कार्यों में जिन्हें मैं भारी बार उपयोग करने की उम्मीद करता हूं, मैं हमेशा बहुत सारे चेक सामने रखता हूं, और उसके बाद कोड को वास्तविक कार्यान्वयन के लिए कॉल करता हूं।

मैं भी इस तरह (जब varargin का उपयोग नहीं) वैकल्पिक आर्ग्युमेंट की संरचना करने के लिए करते हैं:

function x = myfcn(arg1, opt_arg2) 
if nargin < 2 
    arg2 = 'default'; 
else 
    arg2 = opt_arg2; 
end 

के रूप में मुझे लगता है कि यह यह और भी स्पष्ट फ़ाइल जो तर्क वैकल्पिक होने की उम्मीद है संपादित करते समय बनाता है।

4

SCFrench द्वारा सूचीबद्ध कारणों के लिए मैं NARGIN विकल्प के साथ जाऊंगा।एक अतिरिक्त लाभ यह है: मैं अक्सर अपने आप को एक SWITCH बयान के साथ संयोजन के रूप में इसका उपयोग जब मैं अधिक से अधिक 2 इनपुट तर्क है लगता है:

function outArgs = my_fcn(inArg1,inArg2,inArg3) 
    switch nargin, 
    case 0, % No input case 
     error('Not enough inputs!'); 
    case 1, % Set last 2 inputs to default 
     inArg2 = 'yes'; 
     inArg3 = 'on'; 
    case 2, % Set last input to default 
     inArg3 = 'on'; 
    end 
    ... 
    % Checking of variable types and values would go here! 
    ... 
end 
+0

यह आसान लगता है, लेकिन मुझे आश्चर्य है कि, कि अगर एक प्रदर्शन के साथ आता है दंड... – embert

3

उन लोगों के लिए MATLAB R2007b या बाद का उपयोग कर,
यहाँ एक बेहतर जवाब है: InputParser

यह किसी भी अतिरिक्त, निष्कासन, नामकरण और तर्कों के पुनर्मूल्यांकन को सिंक्रनाइज़ करने की परेशानी को बचाता है।

(यदि आप अपने कोडिंग शैली पर निर्भर करेगा बचाने के लिए, लेकिन वहाँ InputParser तुलना में एक अधिक साफ रास्ता नहीं है कितना।)

मैं गति के लिए यह परीक्षण नहीं किया, लेकिन यदि आप कार्य करने के लिए 1000 से अधिक मिलीसेकेंड लेता है रन, इनपुटपर्सर की गति से चिंतित होने का कोई कारण नहीं है।

उदाहरण:

function AbCdEfGhIj(ffff, ggggg, varargin) 
opts = inputParser; 
opts.addRequired('ffff', @(p)(ischar(p) && size(p,1)==1 || iscell(p))); 
opts.addRequired('ggggg', @(p)(iscell(p) && all(cellfun(@ischar,p)))); 
opts.addOptional('Recursive', false, @islogical); 
opts.addOptional('IncludeFullPath', logical([]), @islogical); 
opts.parse(ffff, ggggg, varargin{:}); 
opts = opts.Results; 
if isempty(opts.IncludeFullPath), 
    opts.IncludeFullPath = iscell(opts.fffff) || opts.Recursive; 
end 
2

मैं दृढ़ता से दो कारणों के लिए nargin विकल्प पर exist पसंद करते हैं।

1. लोग हैं, जो अपने स्वयं के कोड पर वापस नज़र डालने सिखाया कभी नहीं थे से कोड का एक बहुत पढ़ने के बाद, मैं सिर्फ इस बात के लिए मजबूत महसूस किया है, के रूप में exist कोड पठनीय बनाता है। उदाहरण के लिए, मुझे इस तरह एक समारोह का सामना करना पड़ा।

[model, accuracy] = epicModelingFunction (dataMatrix, responseVector, indicatorForCategoricalVariables, optionsForInternalFunctions, typeOfDistanceCalculation, notationForMissingValues, isClassificationAndNotRegression, scalingMethod, shouldPlotAllIntermediateStuff) 
% EPICMODELINGFUNCTION is actually a horrible function to read and not epic at all 
% ... 

यह तो की तुलना में पहले दो हर चर अन्य के लिए if nargin < n के बाद किया गया: आपकी सुविधा के लिए मैं चर समझदार नाम दिया था। एकमात्र कारण मैं nargin(n) का पालन कर सकता हूं जो हेडर इनपुट की गणना किए बिना होना चाहिए, यह है कि if nargin < n हमेशा डिफ़ॉल्ट मान के साथ लापता इनपुट की घोषणा (केवल कभी-कभी कोड की कुछ पंक्तियां) और उसके बाद किया जाता था। if nargin < n में कोड के बड़े चक्स के लिए, मैं निश्चित रूप से ट्रैक खो देता हूं।

2.exist वास्तव में पूरा कार्यक्षेत्र जाँच नहीं करता है, तो एक समारोह से कहा जाता है। निश्चित रूप से, कुछ तारों की तुलना में दो संख्याओं की तुलना करना कम महंगा है, लेकिन यदि किसी दिए गए पैरामीटर के लिए डिफ़ॉल्ट मानों को भरने के लिए फ़ंक्शन की शुरुआत में उपयोग किया जाता है, तो यह ठीक है। निम्नलिखित समारोह पर विचार करें:

function testExist(C) 
if exist('B', 'var') 
    disp('''exist'' in a function checks the workspace.') 
elseif exist('C', 'var') 
    disp('''exist'' in a function ignores the variables in the workspace, but checks the function space.') 
else 
    disp('''exist'' is broken or no parameter was given.') 
end 
end 

और फिर निम्नलिखित को निष्पादित: इस उत्पादन में

A = magic(3); 
B = magic(4); 
testExist(A) 

परिणाम:

'exist' in a function ignores the variables in the workspace, but checks the function space. 
संबंधित मुद्दे