4

온도를 변환하는 매우 간단한 GUI를 MATLAB에 작성했습니다. 그것은 학생들의 수업을위한 튜토리얼 역할을하기위한 것입니다. 이상한 일이 일어났습니다. MVC 디자인 패턴과 마찬가지로 모델 오브젝트, 뷰 오브젝트 및 컨트롤러 기능이 있습니다. GUI를 (변환 된 온도)의 출력 필드를 설정하려면 컨트롤러 함수 자체에서이 줄을 실행할 수 있습니다 : views.outputTextField 변환 된 온도와 model.outTemp를 표시하는 GUI 텍스트 필드입니다MATLAB 함수는 배치에 따라 기능을 거부합니다.

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

는 변환 된 온도입니다. 꽤 직설적 인. 뷰 객체는 모든 GUI 사용자에 대한 참조를 가지며 모델 객체에서 새로 변환 된 온도로 필드를 업데이트합니다. 그냥 지금은 뷰에서 익명 함수이며, 이전

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

같은 라인 :

그러나, 나는 오히려 뷰 객체에서보기 기능을 할 것이다, 그래서 나는이 같은 라인을 만드는 시도 목적. 이 방법으로 컨트롤러에서 단순히 views.updateOutputField();으로 함수를 호출하고 뷰 로직을 컨트롤러 로직 밖으로 유지할 수 있습니다. 하지만이 방법은 효과가 없습니다! , 다시 작동 단지 익명 함수를 사용하는 대신 (중복) 기능을 분리하여

views.updateOutputField = @updateOutputField 

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

: (. 그것은 get() 기능 일 것이다 )

대신 나는 다음을 수행해야 . 뭐!? 이것은 나에게 의미가 없습니다. 뷰 및 모델 객체는 전역이며 익명의 함수는 get()으로 작동합니다. 누구가 여기에 무슨 일이 있는지 실마리가 있습니까?

답변

3

두 가지 방법 모두 동일하지 않습니다. 익명 함수의 (일명 람다)의 값은 냉동, 참조 예를 아래에있는됩니다

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

당신은 그것이 작동되도록하려면 다음을 수행 할 수 있습니다

views.updateOutputField = @(outTemp) ... 

을 MATLAB이 작업 공간 컨텍스트를 캡처하는 방법을 알고 싶다면 익명 함수에 FUNCTIONS 함수를 사용하십시오.

viewmodel이 중첩 된 작업 공간에 있지만 본질적으로 동일하므로 예제가 좀 더 복잡합니다.

참고 사항 : Matlab 클래스의 중요한 디자인 패턴 (MVC)도 가르치는 명성!

+0

이것은 사실입니다. 역설적이게도, MVC 디자인 패러다임에서 잠시 동안 작업 한 후이를 일부 학생들에게 보여 주면서 어쨌든 익명의 함수를 사용하지 않는 것이 더 낫다는 것을 깨달았습니다. 조직적인 이유로, 이름을 붙이는 것이 더 낫습니다 (가장 단순한 조건 이외에는). 그럼에도 불구하고이 아주 명확한 설명에 감사드립니다. – russellmania

+0

@ruzel : 답변을 "수락 함"으로 표시하십시오. – Mikhail

+0

미안하지만 그렇게 오래 걸려서 미안 해요. 여전히 StackOverflow가 어떻게 작동하는지 익숙해졌습니다! – russellmania

2

미하일은 right answer입니다. 조금 더 자세히 설명해 드리겠습니다 ...anonymous functions에 대한 MATLAB 문서에서

는 : 인수 목록에 지정된

  • 변수 :

    익명 함수는 일반적으로 변수의 두 가지 유형이 있습니다. 이들은 종종 함수 호출마다 다양합니다.

  • 표현의 본문에 지정된 변수입니다. MATLAB은 변수를 캡처하고 함수 핸들의 수명 내내 상수를 으로 유지합니다. 당신이 당신의 익명 함수 내부 SET로 전화를 걸 때

, 당신은 당신이 개 구조 변수 viewsmodel의 필드에 액세스 할 수 있습니다. 이 값은 익명의 함수가 작성되었을 때의 값으로 고정됩니다. views에 저장된 graphics handles은 그래픽 객체를 삭제 및 다시 작성하지 않는 한 변경되지 않으므로 중요하지 않습니다. 이 때문에 views의 변경되지 않은 그래픽 핸들 만 사용하므로 익명 함수에서 GET을 호출하면 올바르게 작동합니다. 그러나 model의 값이 변경되므로 익명 함수에 인수로 전달할 수 있습니다. 당신이 대신 updateOutputField 기능을 만들 때

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

, 당신은 nested function를 만드는 예를 들면 다음과 같습니다. 중첩 된 함수는 중첩 된 외부 함수에있는 변수에 액세스하므로 viewsmodel을 인수로 전달할 필요가 없습니다. 이러한 변수가 외부 함수에서 변경되면 해당 변경 사항은 익명 함수와 달리 중첩 함수에서도 볼 수 있습니다.

+0

확인. 이 문제에 대해 다시 생각해볼 때까지 5 개월이 걸렸지 만 이제는 이해합니다. 이것은 훌륭합니다! MVC 디자인을 크게 개선 할 수 있습니다. 사실, UI에서 그래픽 객체를 삭제하고 다시 만들 때 모델의 변수를 사용하여 그래픽 객체를 다시 만들 수 있습니다. 많이 개선되었습니다! 정말 고마워. – russellmania

관련 문제