Функции MATLAB отказываются функционировать в зависимости от размещения - PullRequest
4 голосов
/ 28 октября 2009

Я написал очень простой графический интерфейс в MATLAB , который будет преобразовывать температуры. Он предназначен в качестве учебного пособия для класса студентов. Странная вещь произошла, хотя. Как и в любом шаблоне проектирования MVC , есть объект модели, объект представления и функция контроллера. Чтобы установить поле вывода GUI (преобразованную температуру), вы можете запустить эту строку в самой функции контроллера:

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

где views.outputTextField - текстовое поле GUI для отображения преобразованной температуры, а model.outTemp - преобразованная температура. Довольно просто. Объект views имеет ссылки на все графические элементы управления GUI, и это обновляет поле с помощью только что преобразованной температуры в объекте модели.

Однако я предпочел бы иметь функции вида в объекте вида, поэтому я попытался создать строку, подобную этой:

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 ]

3 голосов
/ 28 октября 2009

Оба подхода не эквивалентны. Значения в теле анонимной функции (иначе лямбда) заморожены , см. Пример ниже:

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

Чтобы сделать это, вы можете сделать следующее:

views.updateOutputField = @(outTemp) ...

Если вы хотите узнать, как MATLAB захватывает контекст рабочей области, используйте функцию FUNCTIONS для анонимной функции.

Ваш пример немного сложнее, потому что ваши view и model существуют во вложенном рабочем пространстве, но суть та же.

В качестве дополнительного примечания: слава за преподавание также важного шаблона проектирования (MVC) в классе Matlab!

2 голосов
/ 28 октября 2009

Михаил имеет правильный ответ . Я немного уточню ...

Из документации MATLAB для анонимных функций :

Анонимные функции обычно включают два типа переменных:

  • Переменные, указанные в аргументе список. Они часто варьируются с каждым вызов функции.

  • Переменные, указанные в теле выражение. MATLAB фиксирует эти переменные и держит их постоянными на протяжении всей жизни ручка функции.

Когда вы вызываете SET внутри своей анонимной функции, вы получаете доступ к полям двух ваших структурных переменных views и model. Эти значения остаются неизменными, какими они были при создании анонимной функции. Это не имеет значения для графических дескрипторов , хранящихся в views, поскольку они никогда не изменяются (если вы не удаляете и не воссоздаете графические объекты). Вот почему вызов GET в вашей анонимной функции работает нормально, поскольку он использует только неизмененные графические дескрипторы в views. Однако значения в model изменяются, поэтому вы захотите передать их анонимной функции в качестве аргумента. Например:

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

Когда вы вместо этого создаете updateOutputField функцию, вы создаете вложенную функцию . Вложенные функции имеют доступ к переменным, которые существуют во внешней функции, в которую они вложены, поэтому вам не нужно передавать views и model в качестве аргументов. Когда эти переменные изменяются во внешней функции, это изменение видно и во вложенной функции (в отличие от анонимных функций).

...