我在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()
一起使用。有没有人知道这里发生了什么?
答案 0 :(得分:3)
两种方法都不相同。匿名函数(aka lambda)的 正文 中的值 冻结 ,请参阅下面的示例:
>> ii = 2;
>> val = @() ii+2;
>> val()
ans =
4
>> ii=5;
>> val()
ans =
4
您可以执行以下操作:
views.updateOutputField = @(outTemp) ...
如果您想知道MATLAB如何捕获工作空间上下文,请在匿名函数上使用函数FUNCTIONS
。
您的示例有点复杂,因为您的view
和model
存在于嵌套工作空间中,但本质是相同的。
作为旁注:教学的荣誉也是Matlab课程中重要的设计模式(MVC)!
答案 1 :(得分:2)
米哈伊尔有right answer。我会详细说明......
来自anonymous functions的MATLAB文档:
匿名功能通常包括 两种类型的变量:
参数中指定的变量 名单。这些通常因各自而异 功能调用。
在正文中指定的变量 表达。 MATLAB捕获了这些 变量并保持不变 在整个一生中 功能处理。
当您在匿名函数中调用SET时,您可以访问两个结构变量views
和model
的字段。这些值固定为创建匿名函数时的值。这与views
中存储的graphics handles无关,因为它们永远不会更改(除非您正在删除并重新创建图形对象)。这就是为什么在匿名函数中调用GET可以正常工作,因为它只使用views
中未更改的图形句柄。但是,model
中的值会发生变化,因此您可能希望将它们作为参数传递给匿名函数。例如:
views.updateOutputField = @(model) set(views.outputTextField,'String',...
num2str(round(model.outTemp)));
当您改为创建updateOutputField
功能时,您正在创建nested function。嵌套函数可以访问嵌套它们的外部函数中存在的变量,这就是您不必将views
和model
作为参数传递的原因。当这些变量在外部函数中发生变化时,该变化在嵌套函数中也是可见的(与匿名函数不同)。