当我在攻读EE本科学位时,MATLAB要求每个函数都在自己的文件中定义,即使它是一行程序。
我现在正在攻读研究生学位,我必须用MATLAB写一个项目。这仍然是新版本MATLAB的要求吗?
如果可以在一个文件中放入多个函数,有什么限制吗?例如,可以从文件外部访问文件中的所有函数,还是只能访问与文件名称相同的函数?
注:我使用的是MATLAB版本R2007b。
当我在攻读EE本科学位时,MATLAB要求每个函数都在自己的文件中定义,即使它是一行程序。
我现在正在攻读研究生学位,我必须用MATLAB写一个项目。这仍然是新版本MATLAB的要求吗?
如果可以在一个文件中放入多个函数,有什么限制吗?例如,可以从文件外部访问文件中的所有函数,还是只能访问与文件名称相同的函数?
注:我使用的是MATLAB版本R2007b。
m文件中的第一个函数(即主函数)在m文件被调用时被调用。不要求main函数与m-file具有相同的名称,但为了清晰起见,它应该具有相同的名称。当函数和文件名不同时,必须使用文件名来调用主函数。
m文件中的所有后续函数,称为局部函数(或旧术语中的“子函数”),只能由该m文件中的主函数和其他局部函数调用。其他m文件中的函数不能调用它们。从R2016b开始,你也可以将局部函数添加到脚本中,尽管作用域行为仍然相同(即它们只能从脚本中调用)。
此外,还可以在其他函数中声明函数。它们被称为嵌套函数,并且只能从它们所嵌套的函数中调用。它们还可以访问它们嵌套的函数中的变量,这使得它们非常有用,尽管使用起来有点棘手。
更多值得思考的东西……
有一些方法可以绕过上面概述的正常函数作用域行为,比如像SCFrench和Jonas的回答中提到的那样,将函数句柄作为输出参数传递(从R2013b开始,由localfunctions函数促进)。但是,我不建议养成使用这些技巧的习惯,因为组织函数和文件可能有更好的选择。
例如,假设您在m文件a.m.中有一个主函数a,以及局部函数D、E和f。现在假设您在m文件B.m和C.m中分别有另外两个相关函数B和C,您也希望能够将它们称为D、E和f。
Put D, E, and F each in their own separate m-files, allowing any other function to call them. The downside is that the scope of these functions is large and isn't restricted to just A, B, and C, but the upside is that this is quite simple. Create a defineMyFunctions m-file (like in Jonas' example) with D, E, and F as local functions and a main function that simply returns function handles to them. This allows you to keep D, E, and F in the same file, but it doesn't do anything regarding the scope of these functions since any function that can call defineMyFunctions can invoke them. You also then have to worry about passing the function handles around as arguments to make sure you have them where you need them. Copy D, E and F into B.m and C.m as local functions. This limits the scope of their usage to just A, B, and C, but makes updating and maintenance of your code a nightmare because you have three copies of the same code in different places. Use private functions! If you have A, B, and C in the same directory, you can create a subdirectory called private and place D, E, and F in there, each as a separate m-file. This limits their scope so they can only be called by functions in the directory immediately above (i.e. A, B, and C) and keeps them together in the same place (but still different m-files): myDirectory/ A.m B.m C.m private/ D.m E.m F.m
所有这些都在一定程度上超出了您的问题范围,而且可能比您需要的更详细,但是我认为谈到组织所有m-文件这一更普遍的问题可能会更好。;)
在一个文件中拥有多个单独可访问的函数的唯一方法是使用面向对象编程定义STATIC METHODS。你可以通过myClass.static1(), myClass.static2()等方式访问这个函数。
OOP功能从R2008a开始才得到官方支持,所以除非您想使用旧的、未记录的OOP语法,否则答案是否定的,正如@ g新手所解释的那样。
编辑
在文件中定义可从外部访问的多个函数的另一种方法是创建一个返回多个函数句柄的函数。换句话说,您可以将定义函数调用为[fun1,fun2,fun3]=defineMyFunctions,之后您可以使用out1=fun1(输入)等。
通常,你的问题的答案是否定的,你不能在一个文件中定义一个以上的外部可见函数。不过,可以将函数句柄返回给局部函数,一种方便的方法是将它们设置为结构体的字段。这里有一个例子:
function funs = makefuns
funs.fun1=@fun1;
funs.fun2=@fun2;
end
function y=fun1(x)
y=x;
end
function z=fun2
z=1;
end
下面是如何使用它:
>> myfuns = makefuns;
>> myfuns.fun1(5)
ans =
5
>> myfuns.fun2()
ans =
1
我真的很喜欢SCFrench的答案——我想指出,它可以很容易地修改,使用assignin函数直接将函数导入到工作区。(这样做让我想起了Python“import x from y”的做事方式)
function message = makefuns
assignin('base','fun1',@fun1);
assignin('base','fun2',@fun2);
message='Done importing functions to workspace';
end
function y=fun1(x)
y=x;
end
function z=fun2
z=1;
end
然后这样使用:
>> makefuns
ans =
Done importing functions to workspace
>> fun1(123)
ans =
123
>> fun2()
ans =
1
你也可以把一个main文件中的函数和main函数组合在一起,就像这样:
function [varargout] = main( subfun, varargin )
[varargout{1:nargout}] = feval( subfun, varargin{:} );
% paste your subfunctions below ....
function str=subfun1
str='hello'
然后调用subfun1就像这样: str =主(“subfun1”)
我用Octave在一个.m文件中定义了多个函数,然后在.m文件中使用命令,我需要使用该文件中的函数:
source("mycode.m");
不确定Matlab中是否有。
octave:8> help source
'source' is a built-in function
-- Built-in Function: source (FILE)
Parse and execute the contents of FILE. This is equivalent to
executing commands from a script file, but without requiring the
file to be named `FILE.m'.
沿着与SCFrench的答案相同的路线,但带有更多c#风格的旋转..
我将(并且经常)创建一个包含多个静态方法的类。例如:
classdef Statistics
methods(Static)
function val = MyMean(data)
val = mean(data);
end
function val = MyStd(data)
val = std(data);
end
end
end
因为方法是静态的,所以不需要实例化类。你可以这样调用函数:
data = 1:10;
mean = Statistics.MyMean(data);
std = Statistics.MyStd(data);
从R2017b开始,这是不可能的。有关文件指出:
程序文件可以包含多个函数。如果文件只包含函数定义,则第一个函数是主函数,也是MATLAB与文件名关联的函数。在主函数或脚本代码之后的函数称为局部函数。本地函数仅在文件中可用。
但是,其他答案中建议的变通方法也可以达到类似的效果。
我试过SCFRench和Ru Hasha的八度音。
最后它成功了,但我做了一些修改
function message = makefuns
assignin('base','fun1', @fun1); % Ru Hasha
assignin('base', 'fun2', @fun2); % Ru Hasha
message.fun1=@fun1; % SCFrench
message.fun2=@fun2; % SCFrench
end
function y=fun1(x)
y=x;
end
function z=fun2
z=1;
end
可以在其他'm'文件中调用:
printf("%d\n", makefuns.fun1(123));
printf("%d\n", makefuns.fun2());
更新:
我添加了一个答案,因为+72和+20都不适合我。 我写的那个很好(上周五我在写这篇文章的时候测试了一下)。