MATLAB函数根据放置而拒绝运行

时间:2009-10-27 21:34:44

标签: model-view-controller user-interface matlab anonymous-function

我在MATLAB编写了一个非常简单的GUI来转换温度。它旨在作为一类学生的教程。虽然发生了一件奇怪的事情。与任何MVC设计模式一样,有一个模型对象,一个视图对象和一个控制器函数。为了设置GUI的输出字段(转换后的温度),您可以在控制器功能本身中运行该行:

set(views.outputTextField,'string',num2str(round(model.outTemp)));

其中views.outputTextField是显示转换温度的GUI文本字段,model.outTemp是转换后的温度。非常直截了当。 views对象引用了所有GUI uicontrols,并使用模型对象中新转换的温度更新字段。

但是,我宁愿在视图对象中使用视图函数,所以我尝试创建一个这样的行:

views.updateOutputField = @()set(views.outputTextField,'string',...
    num2str(round(model.outTemp)));

与之前相同,只是现在它是视图对象中的匿名函数。这样我就可以将控制器中的函数调用为views.updateOutputField();,并将视图逻辑保持在控制器逻辑之外。但这种方法不起作用! (使用get()函数。)

相反,我必须做以下事情:

views.updateOutputField = @updateOutputField

function updateOutputField()
    set(views.outputTextField,'string',num2str(round(model.outTemp)));
end

通过分离出函数(冗余)而不是仅仅使用匿名函数,它再次起作用。什么!?这对我来说毫无意义。视图和模型对象是全局的,匿名函数与get()一起使用。有没有人知道这里发生了什么?

2 个答案:

答案 0 :(得分:3)

两种方法都不相同。匿名函数(aka lambda)的 正文 中的值 冻结 ,请参阅下面的示例:

>> ii = 2;
>> val = @() ii+2;
>> val()
ans =
     4
>> ii=5;
>> val()
ans =
     4

您可以执行以下操作:

views.updateOutputField = @(outTemp) ...

如果您想知道MATLAB如何捕获工作空间上下文,请在匿名函数上使用函数FUNCTIONS

您的示例有点复杂,因为您的viewmodel存在于嵌套工作空间中,但本质是相同的。

作为旁注:教学的荣誉也是Matlab课程中重要的设计模式(MVC)!

答案 1 :(得分:2)

米哈伊尔有right answer。我会详细说明......

来自anonymous functions的MATLAB文档:

  

匿名功能通常包括   两种类型的变量:

     
      
  • 参数中指定的变量   名单。这些通常因各自而异   功能调用。

  •   
  • 在正文中指定的变量   表达。 MATLAB捕获了这些   变量并保持不变   在整个一生中   功能处理。

  •   

当您在匿名函数中调用SET时,您可以访问两个结构变量viewsmodel的字段。这些值固定为创建匿名函数时的值。这与views中存储的graphics handles无关,因为它们永远不会更改(除非您正在删除并重新创建图形对象)。这就是为什么在匿名函数中调用GET可以正常工作,因为它只使用views中未更改的图形句柄。但是,model中的值会发生变化,因此您可能希望将它们作为参数传递给匿名函数。例如:

views.updateOutputField = @(model) set(views.outputTextField,'String',...
                                       num2str(round(model.outTemp)));

当您改为创建updateOutputField功能时,您正在创建nested function。嵌套函数可以访问嵌套它们的外部函数中存在的变量,这就是您不必将viewsmodel作为参数传递的原因。当这些变量在外部函数中发生变化时,该变化在嵌套函数中也是可见的(与匿名函数不同)。