2013-08-12 18 views
5

私は、一連の無名関数を構造体とその構造体内のいくつかの変数にグループ化しています。 「自己」、つまり自分の構造を参照する方法はありますか?私が達成したいのは、関数にメンバー変数に基づいていくつかの値を返させることです。簡単にするために、私が持っていると言うstructMATLABに構造体を参照する '自己'はありますか?

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

は、MATLABでの可能性のようなものがありますか?

+5

するのではなく、このために構造体よりもクラスを使用するべきではないでしょうか。 – Dan

+1

迅速な対応とコメントをありがとう。今、私は、MATLABでクラスを定義する方法があることを認識しています。 – radarhead

答えて

9

objected-oriented programmingが(classdef-styleobsolete @-directoryスタイルクラスの両方を含む)MATLABで導入された前に、1 couldは(当然の継承を欠く)閉鎖やネストされた関数を使用して軽量のオブジェクトを作成します。この概念は他の言語でも存在します。ここで

は一例です:

として使用されている
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 

:クロージャを作成するときに、変数をすぐに捕獲されていることを

>> 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 

注意(あなたがするかどうかの関数は、独自のプライベート・コピーを持っています)。したがって、公開されたフィールドの1つを返された構造体から変更した場合、それは囲まれた状態に反映されません(読み込み専用のプロパティとみなされます)。

一つの解決策は、アクセサメソッドを提供することである。

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 

だから今、私たちは言うことができる:

クラスを作成するには、現在推奨されるアプローチのように見え始めている
>> 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 

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 

同様の方法で使用されます。

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

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

我々はまた、/以前のようにaccess methodsセットされますを定義することができます。..

+0

詳細な説明をありがとう。 – radarhead

2

は、これが動作しているようですが、私はあなたではなく、これを行うためにclassstructよりを作成すべきだと思う:

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

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

a.sum(a) 
+1

は同じ正確な答えを追加しようとしていました! –

+0

これは、非常に特定のユースケースでのみ動作します - それが何をしているのか分からない場合は、[完全にねじれます](http://stackoverflow.com/a/18189781/2278029)です。 – horchler

+0

@horchlerどのような場合には、それはねじ込みますか?これはうまくいくので、クラスを使用することを提案しましたので、私はdownovteを本当に理解していませんか? – Dan

0

この変更後

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

a.sum()戻り5で。しかし、後で値の1つを変更するとどうなりますか?たとえば、a.value_1 = 5を設定しますか?今a.sum()が返されます...まだ5。無名関数に渡されるパラメータは、インスタンス化時に評価されます。 2番目の動作を正しく動作させるには、classを使用する必要があります。詳細については、my answer to this questionを参照してください。あなたのように関数ハンドルを使用する唯一の理由は、関数が必要になるまで大きな出力を評価して格納することを避けることです。

+0

お返事ありがとうございます。クラスは私が探していたものですが、MATLABで利用可能であったことを認識していませんでした。 – radarhead

関連する問題