MATLAB - 函数
编写现代而健壮的 MATLAB 函数
Section titled “编写现代而健壮的 MATLAB 函数”函数是任何非简单程序的构建块。在 MATLAB 中,它们对于创建可重用、模块化和可读的代码至关重要。函数封装了一个任务,在自己的独立工作区中操作,并通过输入和输出参数与其他代码通信。
现代函数的结构
Section titled “现代函数的结构”一个现代的 MATLAB 函数,保存在其独立的 .m 文件中,应包含清晰的签名、帮助文本和健壮的输入验证。
function [stat1, stat2] = computeStats(data, options)%COMPUTESTATS 计算输入数据的均值和标准差。% [M, S] = COMPUTESTATS(DATA) 计算向量 DATA 的均值 M 和标准差 S。%% [...] = COMPUTESTATS(..., 'Dimension', DIM) 沿维度 DIM 操作。% [...] = COMPUTESTATS(..., 'RemoveNaNs', true) 在计算前移除 NaN 值。% computation。
arguments data (:,:) {mustBeNumeric, mustBeReal} options.Dimension (1,1) {mustBeInteger} = 1 options.RemoveNaNs (1,1) {mustBeNumericOrLogical} = false end
% 函数体从这里开始 if options.RemoveNaNs data = data(~isnan(data)); end
stat1 = mean(data, options.Dimension); stat2 = std(data, 0, options.Dimension); % 0 表示默认归一化
end % 函数结束这种现代结构的关键组成部分包括:
- 函数签名(Function Signature):
function [out1, ...] = functionName(in1, ...)定义输入和输出。 - 帮助文本(Help Text):签名后连续的注释块,当您键入
help functionName时会显示。它对文档编写至关重要。 arguments块(argumentsblock):(R2019b+) 一种声明性方式,用于定义输入参数、它们的类型、大小和默认值。它取代了旧的、使用nargin和inputParser进行手动解析的方法。
匿名函数是简单的单行函数,无需单独的 .m 文件即可定义。它们对于将函数作为参数传递给另一个函数(例如,用于积分或优化)非常有用。
% 语法: fhandle = @(arglist) expression
% 示例 1:一个简单的幂函数powerFunc = @(x, n) x.^n;result = powerFunc(5, 2) % result = 25
% 示例 2:将匿名函数与 'integral' 配合使用% 计算 x^2 从 0 到 1 的积分quadratic = @(x) x.^2;area = integral(quadratic, 0, 1);您可以在单个 .m 文件中包含多个函数。第一个函数是主函数(其名称与文件相同),可以从外部调用。所有其他函数都是局部函数(以前称为子函数),并且仅对同一文件中的其他函数可见。这是将复杂任务分解为更小、更易于管理的辅助函数的绝佳方式。
% 在名为 'mainTask.m' 的文件中function result = mainTask(inputVal) % 这是主函数 intermediate = helperA(inputVal); result = helperB(intermediate);end
function out = helperA(in) % 这是一个局部函数,只能由 mainTask 和 helperB 调用 out = in * 2;end
function out = helperB(in) % 这是另一个局部函数 out = in + 5;end自 R2016b 起,您还可以在脚本文件中定义局部函数,这对于自包含的示例和任务非常方便。
嵌套函数完全定义在另一个函数内部。它的主要特点是共享其父函数的工作区,允许它访问和修改父函数的变量,而无需将它们作为参数传递。这对于创建具有持久状态的函数非常有用。
若要在多个主函数之间共享辅助函数,但不将其全局暴露,请将它们放在名为 private 的子文件夹中。此文件夹中的函数只能由紧邻父文件夹中的函数调用。这是代码封装和创建库的强大工具。
关于全局变量的警告
Section titled “关于全局变量的警告”虽然 MATLAB 支持可以从任何函数访问的 global 变量,但在现代编程中强烈不推荐使用它们。全局变量使代码难以调试、维护和理解,因为不清楚变量在哪里被修改。始终优先通过函数参数显式传递数据。 如果您需要管理共享状态,请考虑使用类或嵌套函数结构。
函数开发的最佳实践
Section titled “函数开发的最佳实践”- 一任务一函数:每个函数都应有一个单一、明确的目的。
- 使用
arguments块:对于 R2019b 或更高版本编写的任何函数,使用arguments块进行输入验证。它更健壮且可读性更强。 - 编写帮助文本:未来的您(和您的同事)会感谢您。良好的文档与代码本身同样重要。
- 测试您的函数:使用 MATLAB 单元测试框架为您的函数创建自动化测试。这可确保它们正常工作,并防止在您进行更改时出现回归(
buildtest命令或测试浏览器 UI)。 - 使用项目组织:对于大型应用程序,使用 MATLAB 项目(
.prj文件)以结构化方式管理文件、路径和依赖项。