Что такое дескриптор функции и как он полезен?
может кто-нибудь объяснить мне значение @
(ручка функции) оператор и почему использовать его?
3 ответов
на оператор ручки функции в MATLAB действует по существу как указатель на конкретный экземпляр функции. Некоторые из других ответов обсудили некоторые из его применений, но я добавлю еще одно использование здесь, которое я часто имею для него: поддержание доступа к функциям, которые больше не "в области".
например, следующая функция возвращает значение count
, а затем возвращает дескриптор функции вложенной функции increment
:
function fHandle = start_counting(count)
disp(count);
fHandle = @increment;
function increment
count = count+1;
disp(count);
end
end
С помощью функции increment
это вложенные функции, его можно использовать только в пределах функции 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
обратите внимание, как мы можем продолжать увеличивать счет, даже если мы вне функции start_counting
. Но вы можете сделать что-то еще более интересным вызовом 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
обратите внимание, что эти два разных счетчика работают независимо друг от друга. Функция обрабатывает fh
и fh2
укажите на различные экземпляры функции increment
с различными рабочими областями, содержащими уникальные значения для count
.
в дополнение к выше, используя дескрипторы функций в сочетании с вложенными функциями также могут помочь оптимизировать дизайн GUI, как я иллюстрирую в этот другой так пост.
функциональные ручки-чрезвычайно мощный инструмент в matlab. Хорошее начало-прочитать онлайн-справку, которая даст вам гораздо больше, чем я могу. В командной строке введите:
doc function_handle
дескриптор функции-это простой способ создать функцию в одной строке. Например, предположим, что я хочу численно интегрировать функцию sin (k*x), где k имеет некоторое фиксированное внешнее значение. Я мог бы использовать встроенную функцию, но функция обработки намного аккуратнее. Определить функция
k = 2;
fofx = @(x) sin(x*k);
теперь я могу оценить функцию fofx в командной строке. MATLAB знает, что такое k, поэтому теперь мы можем использовать fofx в качестве функции.
fofx(0.3)
ans =
0.564642473395035
на самом деле, мы можем передать fofx вокруг, эффективно как переменная. Например, давайте вызовем quad для численного интегрирования. Я выберу интервал [0, pi / 2].
quad(fofx,0,pi/2)
ans =
0.999999998199215
как вы можете видеть, quad сделал численное интегрирование. (Кстати, встроенная функция была бы, по крайней мере, порядка 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.
аккуратная вещь о ручке функции-вы можете определить ее на лету. Минимизировать функцию cos (x) через интервал [0,2*pi]?
xmin = fminbnd(@(x) cos(x),0,2*pi)
xmin =
3.14159265358979
есть много, много других применений для дескрипторов функций в MATLAB. Я только поцарапал поверхность.
отказ от ответственности: код не проверял...
оператор дескриптора функции позволяет создавать ссылку на функцию и передавать ее так же, как и любую другую переменную:
% 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 имеет более полное описание синтаксиса Matlab и описывает некоторые другие использования для дескрипторов функций, таких как графические обратные вызовы.