是否可以在MATLAB中为每个文件定义多个函数,并从该文件外部访问它们?

Nat*_*man 209 matlab scope file function function-declaration

当我在EE攻读本科学位时,MATLAB要求每个函数都在自己的文件中定义,即使它是一个单行程序.

我现在正在攻读研究生学位,我必须在MATLAB中编写一个项目.这仍然是新版MATLAB的要求吗?

如果可以在文件中放置多个函数,是否有任何限制?例如,文件中的所有函数都可以从文件外部访问,还是只能从与文件同名的函数中访问?

注意:我使用的是MATLAB版本R2007b.

gno*_*ice 266

调用该m文件时,将调用m文件中的第一个函数(即主函数).它不是必需的,主要的功能具有相同的名称为M文件,但为了清楚起见,它应该.当函数和文件名不同时,必须使用文件名来调用main函数.

m文件中的所有后续函数(称为本地函数(或旧术语中的"子函数"))只能由该m文件中的main函数和其他本地函数调用.其他m文件中的函数无法调用它们.从R2016b开始,您也可以向脚本添加本地函数,尽管作用域行为仍然相同(即它们只能在脚本中调用).

此外,您还可以其他函数中声明函数.这些被称为嵌套函数,这些函数只能在它们嵌套的函数中调用.他们也可以访问嵌套它们的函数中的变量,这使得它们非常有用,尽管使用起来有些棘手.

更多值得思考的东西......

围绕上面概述的正常函数作用域行为有一些方法,例如将函数句柄作为输出参数传递,如SCFrenchJonas的答案中所述(从R2013b开始,由localfunctions函数促进).但是,我不建议习惯于采用这种技巧,因为组织你的功能和文件可能有更好的选择.

例如,假设你有一个主要功能A在m文件A.m,与当地职能一起D,EF.现在让我们假设你有两个其他相关功能B,并C在M文件B.mC.m分别,你也希望能够呼吁D,EF.以下是您的一些选择:

  • D,EF每个放在他们自己独立的m文件中,允许任何其他函数调用它们.缺点是,这些功能的范围很广,并不仅仅限于A,BC,但上涨空间,这是非常简单的.

  • 创建一个defineMyFunctionsm文件(就像在Jonas的例子中一样)D,使用E,和F作为本地函数和一个简单地返回函数句柄的main函数.这允许您保留D,E并且F在同一个文件中,但它不会对这些函数的范围做任何事情,因为任何defineMyFunctions可以调用的函数都可以调用它们.然后,您还必须担心将函数句柄作为参数传递,以确保将它们放在需要它们的位置.

  • 复制D,EF进入B.mC.m本地功能.这限制了它们的使用范围,只是A,BC,但是更新和维护代码是一场噩梦,因为你在不同的地方有三个相同代码的副本.

  • 使用私人功能!如果你有A,B以及C在同一目录下,你可以创建一个名为的子目录private和地点D,E以及F在那里,每一个都是独立的m文件.这限制了它们的范围,使他们只能通过功能,在目录正上方叫(即A,BC),并在同一个地方让他们在一起(但仍不同的m文件):

    myDirectory/
        A.m
        B.m
        C.m
        private/
            D.m
            E.m
            F.m
    
    Run Code Online (Sandbox Code Playgroud)

所有这些都超出了你的问题的范围,并且可能比你需要的更详细,但我认为可能很好地触及组织所有m文件的更普遍的关注.;)

  • 最喜欢的答案选项看起来像这个`^`,@ idigas (3认同)

SCF*_*nch 77

通常,您的问题的答案是否定的,您不能为每个文件定义多个外部可见功能.但是,您可以将函数句柄返回到本地函数,一种方便的方法是将它们作为结构的字段.这是一个例子:

function funs = makefuns
  funs.fun1=@fun1;
  funs.fun2=@fun2;
end

function y=fun1(x)
  y=x;
end

function z=fun2
  z=1;
end
Run Code Online (Sandbox Code Playgroud)

以下是它的使用方法:

>> myfuns = makefuns;
>> myfuns.fun1(5)    
ans =
     5
>> myfuns.fun2()     
ans =
     1
Run Code Online (Sandbox Code Playgroud)


Jon*_*nas 36

在单个文件中具有多个可单独访问的函数的唯一方法是使用面向对象的编程来定义STATIC METHODS.您将访问该功能myClass.static1(),myClass.static2()等等.

OOP功能仅在R2008a之后才得到官方支持,所以除非你想使用旧的,未记录的OOP语法,否则你的答案是否定的,正如@gnovice所解释的那样.

编辑

在文件中定义可从外部访问的多个函数的另一种方法是创建一个返回多个函数句柄的函数.换句话说,你可以将你的定义函数称为[fun1,fun2,fun3]=defineMyFunctions,之后你可以使用out1=fun1(inputs)等.


Ru *_*sha 23

我非常喜欢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
Run Code Online (Sandbox Code Playgroud)

然后使用:

>> makefuns
ans =
Done importing functions to workspace

>> fun1(123)
ans =
   123

>> fun2()
ans =
     1
Run Code Online (Sandbox Code Playgroud)


Sma*_*Man 9

与SCFrench的答案一样,但更多C#风格的旋转......

我会(并且经常会)创建一个包含多个静态方法的类.例如:

classdef Statistics

    methods(Static)
        function val = MyMean(data)
            val = mean(data);
        end

        function val = MyStd(data)
            val = std(data);
        end
    end

end
Run Code Online (Sandbox Code Playgroud)

由于方法是静态的,因此您无需实例化该类.您可以按如下方式调用函数:

data = 1:10;

mean = Statistics.MyMean(data);
std = Statistics.MyStd(data);     
Run Code Online (Sandbox Code Playgroud)