2009-04-28 16 views

उत्तर

47

MATLAB में function handle operator अनिवार्य रूप से एक फ़ंक्शन के विशिष्ट उदाहरण के लिए सूचक की तरह कार्य करता है। कुछ अन्य उत्तरों ने इसके कुछ उपयोगों पर चर्चा की है, लेकिन मैं यहां एक और उपयोग जोड़ूंगा जो मेरे पास अक्सर होता है: उन कार्यों तक पहुंच बनाए रखना जो अब "दायरे में नहीं हैं"।

उदाहरण के लिए, निम्नलिखित समारोह एक मूल्य count initializes, और फिर एक नेस्टेड समारोह increment करने के लिए एक समारोह संभाल रिटर्न:

function fHandle = start_counting(count) 

    disp(count); 
    fHandle = @increment; 

    function increment 
    count = count+1; 
    disp(count); 
    end 

end 

समारोह increment एक nested function है के बाद से, यह केवल समारोह के भीतर इस्तेमाल किया जा सकता start_counting (यानि start_counting का कार्यक्षेत्र इसका "दायरा" है)। हालांकि, फ़ंक्शन increment पर एक हैंडल लौटकर, मैं अभी भी start_counting के बाहर इसका उपयोग कर सकता हूं, और यह अभी भी start_counting के कार्यक्षेत्र में चरों तक पहुंच को बरकरार रखता है! यही कारण है कि मुझे यह करने के लिए अनुमति देता है:

>> fh = start_counting(3); % Initialize count to 3 and return handle 
    3 

>> fh(); % Invoke increment function using its handle 
    4 

>> fh(); 
    5 

सूचना कैसे हम गिनती incrementing भले ही हम समारोह start_counting के बाहर हैं रख सकते हैं।

>> fh2 = start_counting(-4); 
    -4 

>> fh2(); 
    -3 

>> fh2(); 
    -2 

>> fh(); % Invoke the first handle to increment 
    6 

>> fh2(); % Invoke the second handle to increment 
    -1 

सूचना है कि इन दो अलग-अलग काउंटरों स्वतंत्र रूप से संचालित: लेकिन आप और भी दिलचस्प एक अलग संख्या के साथ फिर से start_counting बुला और अन्य चर में संग्रहीत समारोह संभाल द्वारा कुछ कर सकते हैं। फ़ंक्शन fh और fh2 फ़ंक्शन increment के विभिन्न उदाहरणों के साथ count के लिए अद्वितीय मान वाले विभिन्न कार्यस्थानों के साथ इंगित करता है।

उपर्युक्त के अतिरिक्त, नेस्टेड फ़ंक्शंस के संयोजन के साथ फ़ंक्शन हैंडल का उपयोग करने से GUI डिज़ाइन को सुव्यवस्थित करने में भी मदद मिल सकती है, जैसा कि मैंने this other SO post में दिखाया है।

+2

एक बात यह ध्यान रखना महत्वपूर्ण है कि @ ऑपरेटर द्वारा बनाए गए फ़ंक्शन कीवर्ड और फ़ंक्शंस के साथ बनाए गए फ़ंक्शंस में अलग-अलग स्कोपिंग नियम हैं। hGetCount = @ getCount; फ़ंक्शन सी = getCount; c = गिनती; समाप्त; जैसा कि आप उपरोक्त वर्णन करते हैं, मूल्यांकन समय पर (गणनात्मक स्कोपिंग का उपयोग करके) गणना चर पर लुकअप वैरिएबल का लुकअप करता है। समारोह hGetCount = @() गिनती; निर्माण समय पर प्रतिबिंबित वैल्यू वैरिएबल का मान होगा। –

+2

फ़ंक्शन हैंडल आपको मुख्य फ़ंक्शन के बाहर से नेस्टेड फ़ंक्शंस या सबफ़ंक्शन के साथ काम करने की अनुमति देता है। वे आपको जीयूआई प्रोग्रामिंग में सहायता कर सकते हैं। –

+0

@ श्री फूज़: अच्छा बिंदु! @ ऑपरेटर के साथ बनाया गया बेनामी फ़ंक्शन बस वर्कस्पेस में मौजूद चर के लिए मानों को प्रतिस्थापित करेगा, जबकि "सामान्य" फ़ंक्शंस में वेरिएबल्स संग्रहीत करने के लिए अपने स्वयं के कार्यस्थान होते हैं। – gnovice

15

अस्वीकरण: कोड का परीक्षण नहीं किया ...

समारोह संभाल ऑपरेटर आप एक समारोह के लिए एक संदर्भ बना सकते हैं और किसी भी अन्य चर की तरह चारों ओर इसे पारित करने के लिए अनुमति देता है:

% function to add two numbers 
function total = add(first, second) 
    total = first + second; 
end 

% this variable now points to the add function 
operation = @add; 

एक बार आपके द्वारा एक समारोह संभाल मिल गया है, तो आप यह सिर्फ एक नियमित रूप से समारोह की तरह आह्वान कर सकते हैं:

operation(10, 20); % returns 30 

एक समारोह के बारे में अच्छी बात यह है संभालती है कि आप उन्हें चारों ओर सिर्फ किसी भी अन्य संगठनों की तरह पारित कर सकते हैं है एर डेटा, ताकि आप उन कार्यों को लिख सकें जो अन्य कार्यों पर कार्य करते हैं। इस बार आप आसानी से व्यापार तर्क को अलग करने के लिए अनुमति देता है:

% prints hello 
function sayHello 
    disp('hello world!'); 
end 

% does something five times 
function doFiveTimes(thingToDo) 
    for idx = 1 : 5 
     thingToDo(); 
    end 
end 

% now I can say hello five times easily: 
doFiveTimes(@sayHello); 

% if there's something else I want to do five times, I don't have to write 
% the five times logic again, only the operation itself: 
function sayCheese 
    disp('Cheese'); 
end 
doFiveTimes(@sayCheese); 

% I don't even need to explicitly declare a function - this is an 
% anonymous function: 
doFiveTimes(@() disp('do something else')); 

Matlab documentation मैटलैब वाक्य रचना की पूरी विवरण नहीं है, और कुछ अन्य उपयोगों का वर्णन समारोह ग्राफिक्स कॉलबैक की तरह संभालती के लिए।

17

फ़ंक्शन हैंडल matlab में एक बेहद शक्तिशाली उपकरण हैं। एक अच्छी शुरुआत ऑनलाइन सहायता को पढ़ना है, जो आपको जितना संभव हो उतना अधिक देगी। कमांड प्रॉम्प्ट पर,

doc function_handle 

एक फ़ंक्शन हैंडल एक पंक्ति में फ़ंक्शन बनाने का एक आसान तरीका है। उदाहरण के लिए, मान लीजिए कि मैं फ़ंक्शन पाप (के * एक्स) को संख्यात्मक रूप से एकीकृत करना चाहता हूं, जहां के कुछ निश्चित, बाहरी मान हैं। मैं एक इनलाइन फ़ंक्शन का उपयोग कर सकता हूं, लेकिन एक फ़ंक्शन हैंडल बहुत साफ है। एक फ़ंक्शन को परिभाषित करें

k = 2; 
fofx = @(x) sin(x*k); 

देखें कि अब मैं कमांड लाइन पर फ़ंक्शन fofx का मूल्यांकन कर सकता हूं। MATLAB जानता है कि क्या है, इसलिए हम अब फ़ंक्शन के रूप में fofx का उपयोग कर सकते हैं।

fofx(0.3) 
ans = 
     0.564642473395035 

असल में, हम एक चर के रूप में प्रभावी रूप से fofx पास कर सकते हैं। उदाहरण के लिए, संख्यात्मक एकीकरण करने के लिए क्वाड कॉल करें। मैं अंतराल [0, पीआई/2] उठाऊंगा।

quad(fofx,0,pi/2) 
ans = 
     0.999999998199215 

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

x = linspace(0,pi,1000); 
tic,y = fofx(x);toc 
Elapsed time is 0.000493 seconds. 

तुलना की वैसे, एक इनलाइन समारोह का प्रयास करें।

finline = inline('sin(x*k)','x','k'); 
tic,y = finline(x,2);toc 
Elapsed time is 0.002546 seconds. 

फ़ंक्शन हैंडल के बारे में एक साफ चीज़ यह है कि आप इसे फ्लाई पर परिभाषित कर सकते हैं। अंतराल [0,2 * पीआई] पर फ़ंक्शन कोस (x) को कम करें?

xmin = fminbnd(@(x) cos(x),0,2*pi) 
xmin = 
      3.14159265358979 

MATLAB में फ़ंक्शन हैंडल के लिए कई अन्य उपयोग हैं। मैंने केवल सतह को खरोंच कर लिया है।

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