在我攻读EE的本科学位时,MATLAB要求每个函数都必须在自己的文件中定义,即使它是单行的也是如此。
我现在正在攻读研究生学位,所以我必须在MATLAB中编写一个项目。仍然需要更新版本的MATLAB吗?
如果可以在一个文件中放置多个功能,是否对此有任何限制?例如,可以从文件外部访问文件中的所有功能,还是仅从名称相同的功能访问文件?
注意:我正在使用MATLAB版本R2007b。
在我攻读EE的本科学位时,MATLAB要求每个函数都必须在自己的文件中定义,即使它是单行的也是如此。
我现在正在攻读研究生学位,所以我必须在MATLAB中编写一个项目。仍然需要更新版本的MATLAB吗?
如果可以在一个文件中放置多个功能,是否对此有任何限制?例如,可以从文件外部访问文件中的所有功能,还是仅从名称相同的功能访问文件?
注意:我正在使用MATLAB版本R2007b。
Answers:
m文件中的第一个函数(即main函数)在调用该m文件时被调用。它不是必需的,主要的功能具有相同的名称为M文件,但为了清楚起见,它应该。当函数和文件名不同时,必须使用文件名来调用主函数。
m文件中的所有后续函数(称为本地函数(或旧术语中的“子函数”))只能由该m文件中的main函数和其他本地函数调用。其他m文件中的函数无法调用它们。从R2016b开始,您还可以向脚本中添加本地函数,尽管作用域范围仍然相同(即只能在脚本中调用它们)。
此外,您还可以在其他函数中声明函数。这些称为嵌套函数,并且只能从它们嵌套的函数内部调用它们。它们还可以访问嵌套它们的函数中的变量,这使它们非常有用,尽管使用起来有些棘手。
更多值得深思的...
围绕上面概述的正常函数作用域行为,有一些方法,例如将函数句柄作为输出参数传递,如SCFrench和Jonas的答案中提到的(从R2013b开始,此localfunctions函数为函数提供了便利)。但是,我不建议您养成使用这种技巧的习惯,因为组织功能和文件可能有更好的选择。
例如,假设你有一个主要功能A在m文件A.m,与当地职能一起D,E和F。现在让我们假设你有两个其他相关功能B,并C在M文件B.m和C.m分别,你也希望能够呼吁D,E和F。这里有一些选项:
将D,E和F分别放在各自独立的m文件中,以允许其他任何函数调用它们。缺点是,这些功能的范围很广,并不仅仅限于A,B和C,但上涨空间,这是非常简单的。
创建defineMyFunctions(在Jonas的例子等)m文件用D,E和F作为本地函数和一个主功能,简单地返回函数处理它们。这样,您就可以将D,E和保留F在同一文件中,但是对于这些函数的作用域则不做任何事情,因为任何defineMyFunctions可以调用的函数都可以调用它们。然后,您还必须担心将函数句柄作为参数传递,以确保将它们放在需要的位置。
复制D,E并F进入B.m和C.m本地功能。这限制了它们的使用,只是范围A,B和C,反而使得更新和你的代码是一场噩梦的维护,因为你必须在不同的地方相同的代码的三个副本。
使用私有功能!如果你有A,B以及C在同一目录下,你可以创建一个名为的子目录private和地点D,E以及F在那里,每一个都是独立的m文件。这限制了它们的范围,使他们只能通过功能,在目录正上方叫(即A,B和C),并在同一个地方让他们在一起(但仍不同的m文件):
myDirectory/
A.m
B.m
C.m
private/
D.m
E.m
F.m所有这些都超出了您的问题范围,并且可能比您需要的细节更多,但是我认为最好涉及组织所有m文件的更普遍的关注。;)
在单个文件中拥有多个可单独访问的功能的唯一方法是使用面向对象的编程来定义STATIC方法。您将以myClass.static1(),myClass.static2()等访问该函数。
自R2008a以来,才正式支持OOP功能,因此,除非您要使用未记录的旧OOP语法,否则答案为否,如@gnovice所述。
编辑
在文件中定义可从外部访问的多个函数的另一种方法是创建一个返回多个函数句柄的函数。换句话说,您将定义函数称为[fun1,fun2,fun3]=defineMyFunctions,之后可以使用out1=fun1(inputs)etc。
我真的很喜欢SCFrench的答案-我想指出,可以轻松地对其进行修改,以使用assignin函数将函数直接导入到工作区中。(这样做,使我想起了很多Python的“从y导入x”的方式)
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
assignin('caller',...)会更正确。您可能想从另一个功能中使用这些功能。
与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);
我使用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'.
您也可以将函数与一个主函数组合在一个主文件中,如下所示:
function [varargout] = main( subfun, varargin )
[varargout{1:nargout}] = feval( subfun, varargin{:} );
% paste your subfunctions below ....
function str=subfun1
str='hello'
然后调用subfun1看起来像这样:str = main('subfun1')
从R2017b开始,这在官方上是不可能的。的相关文件规定:
程序文件可以包含多个功能。如果文件仅包含函数定义,则第一个函数是主要函数,并且是MATLAB与文件名关联的函数。遵循主要功能或脚本代码的功能称为局部功能。本地功能仅在文件内可用。
但是,其他答案中建议的解决方法也可以达到类似目的。
终于奏效了: 但是我做了一些修改
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 都不对我起作用八度。我写的那本书很完美(我上周五在后来写这篇文章时对其进行了测试)。
^:@idigas