函数句柄 #
一、函数句柄概述 #
函数句柄是一种存储函数引用的变量,可以将函数作为参数传递:
matlab
% 创建函数句柄
f = @sin; % 内置函数
g = @my_func; % 自定义函数
% 使用句柄调用函数
f(pi/2) % 1
二、创建函数句柄 #
2.1 命名函数句柄 #
matlab
% 内置函数
f = @sin;
f(pi/2) % 1
% 自定义函数
% 保存为 square.m
function result = square(x)
result = x^2;
end
% 创建句柄
g = @square;
g(5) % 25
2.2 匿名函数句柄 #
matlab
% 匿名函数本身就是句柄
f = @(x) x^2 + 2*x + 1;
f(3) % 16
% 多参数
g = @(x, y) x*y + x + y;
g(2, 3) % 11
2.3 方法句柄 #
matlab
% 类方法句柄
obj = MyClass();
method_handle = @obj.myMethod;
% 调用
method_handle(args);
三、函数句柄属性 #
3.1 查看句柄信息 #
matlab
f = @sin;
% 查看函数名
func2str(f) % 'sin'
% 查看函数信息
functions(f)
% function: 'sin'
% type: 'simple'
% file: ''
% 检查是否为句柄
isa(f, 'function_handle') % true
3.2 句柄比较 #
matlab
f1 = @sin;
f2 = @sin;
f3 = @cos;
% 使用isequal比较
isequal(f1, f2) % true
isequal(f1, f3) % false
% 使用eq比较
f1 == f2 % true
四、函数句柄作为参数 #
4.1 传递给函数 #
matlab
% 接受函数句柄作为参数
function result = apply_function(f, x)
result = f(x);
end
% 使用
apply_function(@sin, pi/2) % 1
apply_function(@(x) x^2, 5) % 25
4.2 数值积分 #
matlab
% 定义被积函数
f = @(x) exp(-x.^2);
% 计算积分
result = integral(f, 0, Inf);
fprintf('积分结果: %.6f\n', result); % 0.886227
4.3 方程求解 #
matlab
% 定义方程
f = @(x) x^2 - 4;
% 求根
roots = fzero(f, 1); % 从1开始搜索
fprintf('根: %.4f\n', roots); % 2.0000
4.4 优化问题 #
matlab
% 定义目标函数
f = @(x) (x(1)-1)^2 + (x(2)-2)^2;
% 最小化
x0 = [0, 0];
[x_opt, f_opt] = fminsearch(f, x0);
fprintf('最优点: (%.4f, %.4f), 最小值: %.4f\n', x_opt(1), x_opt(2), f_opt);
% 最优点: (1.0000, 2.0000), 最小值: 0.0000
五、函数句柄数组 #
5.1 创建句柄数组 #
matlab
% 函数句柄数组
funcs = {@sin, @cos, @tan, @exp};
% 使用
for i = 1:length(funcs)
fprintf('%.4f\n', funcs{i}(pi/4));
end
% 0.7071
% 0.7071
% 1.0000
% 2.1933
5.2 选择性执行 #
matlab
% 根据条件选择函数
operations = struct();
operations.add = @(a, b) a + b;
operations.subtract = @(a, b) a - b;
operations.multiply = @(a, b) a * b;
operations.divide = @(a, b) a / b;
% 使用
op = 'multiply';
result = operations.(op)(10, 5);
fprintf('%s: %d\n', op, result); % multiply: 50
六、回调函数 #
6.1 定时器回调 #
matlab
% 创建定时器
t = timer;
t.TimerFcn = @(~,~) disp('定时器触发');
t.StartDelay = 2; % 2秒后触发
start(t);
pause(3);
delete(t);
6.2 图形回调 #
matlab
% 按钮回调
fig = figure;
btn = uicontrol('Style', 'pushbutton', ...
'String', '点击我', ...
'Position', [100 100 100 30], ...
'Callback', @(~,~) disp('按钮被点击'));
% 关闭图形
delete(fig);
6.3 事件处理 #
matlab
% 定义事件处理函数
function setup_event_handler()
fig = figure;
% 鼠标移动回调
set(fig, 'WindowButtonMotionFcn', @mouse_moved);
function mouse_moved(~, ~)
pos = get(fig, 'CurrentPoint');
title(sprintf('位置: (%.0f, %.0f)', pos(1), pos(2)));
end
end
七、参数化函数句柄 #
7.1 捕获参数 #
matlab
% 创建参数化函数
function f = make_quadratic(a, b, c)
f = @(x) a*x^2 + b*x + c;
end
% 使用
f1 = make_quadratic(1, 0, -1); % x^2 - 1
f2 = make_quadratic(2, 3, 1); % 2x^2 + 3x + 1
f1(2) % 3
f2(1) % 6
7.2 工厂函数 #
matlab
% 函数工厂
function processor = make_processor(method)
switch method
case 'normalize'
processor = @(data) (data - min(data)) / (max(data) - min(data));
case 'standardize'
processor = @(data) (data - mean(data)) / std(data);
case 'log'
processor = @(data) log(data + 1);
otherwise
error('未知方法');
end
end
% 使用
norm_func = make_processor('normalize');
data = [1 2 3 4 5];
normalized = norm_func(data);
八、实用示例 #
8.1 数值微分 #
matlab
function df = numerical_derivative(f, x)
% NUMERICAL_DERIVATIVE 数值微分
h = 1e-8;
df = (f(x + h) - f(x - h)) / (2 * h);
end
% 使用
f = @sin;
df = numerical_derivative(f, pi/4);
fprintf('sin在pi/4处的导数: %.6f (理论值: %.6f)\n', df, cos(pi/4));
8.2 数值积分 #
matlab
function I = simpson_integral(f, a, b, n)
% SIMPSON_INTEGRAL 辛普森积分法
h = (b - a) / n;
x = linspace(a, b, n + 1);
y = f(x);
I = h/3 * (y(1) + y(end) + 4*sum(y(2:2:end-1)) + 2*sum(y(3:2:end-2)));
end
% 使用
f = @(x) sin(x);
I = simpson_integral(f, 0, pi, 100);
fprintf('积分结果: %.6f (理论值: 2.000000)\n', I);
8.3 自定义映射函数 #
matlab
function result = my_map(func, data)
% MY_MAP 对数据应用函数
if iscell(data)
result = cellfun(func, data, 'UniformOutput', false);
else
result = arrayfun(func, data);
end
end
% 使用
data = [1 2 3 4 5];
squares = my_map(@(x) x^2, data);
% [1 4 9 16 25]
names = {'apple', 'banana'};
upper_names = my_map(@upper, names);
% {'APPLE', 'BANANA'}
九、最佳实践 #
9.1 选择合适的句柄类型 #
matlab
% 简单函数:匿名函数
f = @(x) x^2;
% 复杂函数:命名函数
% 保存为 complex_calculation.m
function result = complex_calculation(x)
% 复杂计算
end
% 使用句柄
f = @complex_calculation;
9.2 文档化函数句柄 #
matlab
% 为参数化函数添加文档
function f = make_gaussian(mu, sigma)
% MAKE_GAUSSIAN 创建高斯函数句柄
% f = make_gaussian(mu, sigma) 返回高斯函数句柄
%
% 输入:
% mu - 均值
% sigma - 标准差
%
% 输出:
% f - 函数句柄 @(x) 高斯函数值
%
% 示例:
% f = make_gaussian(0, 1);
% y = f(0); % 0.3989
f = @(x) 1/(sigma*sqrt(2*pi)) * exp(-(x-mu).^2/(2*sigma^2));
end
9.3 错误处理 #
matlab
function result = safe_apply(f, x)
% SAFE_APPLY 安全应用函数
if ~isa(f, 'function_handle')
error('第一个参数必须是函数句柄');
end
try
result = f(x);
catch ME
warning('函数执行失败: %s', ME.message);
result = NaN;
end
end
十、总结 #
本章学习了:
- 创建句柄:命名函数、匿名函数
- 句柄属性:func2str、functions
- 作为参数:传递给其他函数
- 句柄数组:存储多个函数
- 回调函数:定时器、图形回调
- 参数化句柄:捕获外部变量
- 实用示例:数值微分、积分
下一章将学习递归函数。
最后更新:2026-03-27