2013-08-12 12 views
5

Łączę zestaw anonimowych funkcji w strukturę i niektóre zmienne w tej strukturze. Czy istnieje sposób na odnoszenie się do "ja", tj. Do własnej struktury? Chciałbym, aby funkcja zwracała pewne wartości w oparciu o zmienne składowe. Dla uproszczenia, że ​​mam struct, gdzieCzy istnieje "self", aby odnieść własną strukturę w MATLAB?

a.value_1 = 3; 
a.value_2 = 2; 
a.sum = @()(self.value_1 + self.value_2) 

Czy istnieje coś takiego jak to możliwe w programie MATLAB?

+5

Jeżeli nie jesteś raczej użyć klasy niż struktury dla tego? – Dan

+1

Dzięki za szybkie odpowiedzi i komentarze. Teraz zdaję sobie sprawę, że istnieje sposób definiowania klasy w MATLAB. – radarhead

Odpowiedz

9

Przed objected-oriented programming został wprowadzony w MATLAB (w tym zarówno classdef-style i klas stylu obsolete @-directory), jeden could tworzenia lekkich obiektów za pomocą zamknięć i funkcji zagnieżdżonych (brakuje dziedziczenie oczywiście). Ta koncepcja istnieje również w innych językach.

Oto przykład:

function s = mystruct() 
    s = struct('value_1',[], 'value_2',2, 'sum',@mysum); 
    s.value_1 = 3; 

    function out = mysum() 
     out = s.value_1 + s.value_2; 
    end 
end 

który jest używany jako:

>> s = mystruct() 
s = 
    value_1: 3 
    value_2: 2 
     sum: @mystruct/mysum 
>> s.value_1 = 10;  % NOTE: this wont do what you expect! 
>> s.sum() 
ans = 
    5 

Zauważ, że zmienne są natychmiast schwytany podczas tworzenia zamknięcie (funkcje posiadają własną kopię, jeśli będzie). Jeśli więc zmienisz jedno z odsłoniętych pól ze zwróconej struktury, nie zostanie ono odzwierciedlone w stanie zamkniętym (pomyśl o nich jako o właściwościach tylko do odczytu).

Jednym z rozwiązań jest zapewnienie metody dostępowe:

function obj = mystruct() 
    % think of those as private properties 
    value_1 = 3; 
    value_2 = 2; 

    % returned object (this or self) 
    obj = struct(); 

    % public accessors for properties 
    obj.value_1 = @accessValue1; 
    function out = accessValue1(in) 
     if nargin > 0, value_1 = in; end 
     out = value_1; 
    end 
    obj.value_2 = @accessValue2; 
    function out = accessValue2(in) 
     if nargin > 0, value_2 = in; end 
     out = value_2; 
    end 

    % member method 
    obj.sum = @mysum; 
    function out = mysum() 
     out = value_1 + value_2; 
    end 
end 

Więc teraz możemy powiedzieć:

>> s = mystruct() 
s = 
    value_1: @mystruct/accessValue1 
    value_2: @mystruct/accessValue1 
     sum: @mystruct/mysum 
>> x = s.value_1(); % get 
>> s.value_1(10);  % set 
>> s.sum() 
ans = 
    12 

Który zaczyna wyglądać bieżącego Zalecane podejście do tworzenia klas:

classdef mystruct < handle 
    properties 
     value_1 = 3; 
     value_2 = 2; 
    end 
    methods 
     function out = sum(obj) 
      out = obj.value_1 + obj.value_2; 
     end 
    end 
end 

Używany w podobny sposób:

>> s = mystruct() 
s = 
    mystruct with properties: 

    value_1: 3 
    value_2: 2 
>> s.value_1 = 10; 
>> s.sum 
ans = 
    12 

Możemy również zdefiniować get/set access methods jak wcześniej ..

+0

Dzięki za szczegółowe wyjaśnienie. – radarhead

2

To wydaje się działać, ale myślę, że należy raczej stworzyć class niż struct to zrobić:

a.value_1 = 3; 
a.value_2 = 2; 

a.sum = @(x)(x.value_1 + x.value_2) 

a.sum(a) 
+1

zamierzał dodać tę samą dokładną odpowiedź! –

+0

Działa to tylko w ściśle określonym przypadku - będzie to (całkowicie wkręcić) (http://stackoverflow.com/a/18189781/2278029) w innych, jeśli ktoś nie zrozumie, co robi. – horchler

+0

@horchler W jakich przypadkach może to zepsuć? To działa i zaproponowałem raczej użycie klasy, więc tak naprawdę nie rozumiem downovte? – Dan

0

Dzięki tej zmianie

a.value_1 = 3; 
a.value_2 = 2; 
a.sum = @()(a.value_1 + a.value_2) 

Następnie a.sum() zwrotów 5. Ale co się stanie, gdy zmienisz jedną z wartości, a później np. Ustawisz a.value_1 = 5? Teraz a.sum() zwraca ... nadal 5. Parametry przekazywane do anonimowej funkcji są oceniane po utworzeniu instancji. Jeśli chcesz, aby drugie zachowanie działało poprawnie, musisz użyć class. Aby uzyskać więcej informacji, patrz my answer to this question. Jedynym powodem używania uchwytu funkcji, takiego jaki masz, jest unikanie oceniania i przechowywania dużego wyjścia funkcji, dopóki nie będzie potrzebne.

+0

Dzięki za odpowiedź. Klasa jest tym, czego szukałem, ale nie zdawałem sobie sprawy, że była dostępna w MATLAB. – radarhead

Powiązane problemy