2

以下aの構造体として定義されているとします。Rのdputに相当するコマンドを見つけようとしましたが、ここでエラーが発生しました。たとえば、以下はフォームでなければならないことはstruct('const',1,'terms',{{struct(),struct()}})わかっていますが、構造の内部に何が格納されているかは、hereのようなコマンドで確認しないとわかりません。時間がかかります。

では、Matlab で構造体を生成する元のコマンドを確認できるコマンドはどれですか?

>> a

a =

    const: 1
    terms: {[1x1 struct]  [1x1 struct]}
4

3 に答える 3

3

コメント

構造体からクラスに切り替えることはできますか? その場合は、構造体を模倣するものを作成し、変更されるたびに stack = dbstack を呼び出してスタックを取得し、変更とともにスタックを保存します。変更を行ったコマンドは、後でスタック内の行番号から自動的に取得できます。

コメントでこれに対するフォローアップ要求として、構造体機能を提供し、その割り当ての記録も保持するクラスの例を次に示します。

classdef utstruct
    properties (SetAccess = private)
        modifications
    end

    properties (Dependent, SetAccess = private)
        myStruct
    end

    properties (Access = private)
        m_struct
    end

    methods
        function self = utstruct(varargin)
            if nargin > 0
                self.m_struct = builtin('struct', varargin{:});
            else
                self.m_struct = builtin('struct');
            end
            % Should update self.modifications here
        end

        function B = subsref(self, s)
            if any(strcmp(s(1).subs, properties(self)))
                B = builtin('subsref', self, s);
            else
                B = subsref(self.m_struct, s);
            end
        end

        function A = subsasgn(self, s, b)
            self.m_struct = subsasgn(self.m_struct, s, b);

            newMod = builtin('struct');
            newMod.type = 'subsasgn';
            newMod.modData = {s b};
            newMod.stack = dbstack;
            self.modifications = [self.modifications; newMod];

            A = self;
        end

        function disp(self)
            disp(self.m_struct);
        end

        function names = fieldnames(self, varargin)
            names = fieldnames(self.m_struct, varargin{:});
        end

        function C = cat(self, dim, varargin)
            uts = cellfun(@(x)isa(x, 'utstruct'), varargin);
            varargin{uts} = cellfun(@(x)x.m_struct, varargin(uts));
            varargin = [{self.m_struct} varargin];
            self.m_struct = cat(dim, varargin{:});

            % Should update self.modifications here

            C = self;
        end

        function C = horzcat(self, varargin)
            C = self.cat(1, varargin{:});
        end

        function C = vertcat(self, varargin)
            C = self.cat(2, varargin{:});
        end

        function value = get.myStruct(self)
            value = self.m_struct;
        end
    end
end

初期化/連結操作が発生したときに変更配列を更新するコードを追加する必要があります。

subsrefとのsubsasgnオーバーライドは、(すべてのアクティビティを実際の構造体に延期することによって) 構造体のように動作させるための重要なポイントですが、他のオーバーライドも同様fieldnamesdispあり、同じことを行います。構造体へのすべての割り当ての記録にはsubsasgn、割り当てを生成したスタックと共に保持されます。

注:これがビルトインと完全に互換性を持つようにするには、structおそらくさらにいくつかのメソッドをオーバーライドする必要がありますが、これで十分です。MATLAB 組み込み型のサブクラス化を参照してください。

編集:例をもう少し堅牢にしました。これは、あるべき値クラスになり、連結で機能します。

編集:struct(...)関数を再定義することにより、検索と置換を使用して既存の呼び出しをリファクタリングすることを避けることができますstruct

function s = struct(varargin)
% STRUCT    Overrides default struct function to provide unit-testable structs
%
%   Set global variable unitTestStructEnabled to true to enable this
%   function.
%
global unitTestStructEnabled;

if isempty(unitTestStructEnabled)
    unitTestStructEnabled = false;
end

if unitTestStructEnabled
    s = utstruct(varargin{:});
else
    s = builtin('struct', varargin{:});
end

最初に構造体を作成するときに警告が表示されるため (オフにすることもできますが、それによって他の問題が隠れる可能性があります)、おそらくそれをパスにずっとぶら下げたくないでしょう。通常はパスにないフォルダーを作成し、単体テスト用のパス ( addpath/ rmpath) に一時的に追加します。

于 2013-04-13T09:53:05.930 に答える
1

あなたの質問に完全に答えるわけではありませんが、 Urs のvsize()が役立ちます:

% Create some complicated variable
v(1).a{1}=sparse(magic(3)+2i*magic(3));
v(2).a{2}={struct('FA',{'a','bb'},'FB',{magic(5),{}})};
v(2).b{2}=@(x) sind(x);

% Dissect        
P = vsize(v);

% -------------------------
%       1998       1998 B *   v = 2:1x2:struct.(2)
% CELL -----        360 B     v[].a = 2:1x1:cell
%       1750        248 B -   v[].a{} = 2:3x3:double.sparse.complex
% CELL -----       1014 B     v[].a = 2:1x2:cell
%       1750          0 B -   v[].a{} = 2:0x0:double
% CELL -----        894 B     v[].a{} = 2:1x1:cell
% STRUCT ---        782 B     v[].a{}{} = 2:1x2:struct.(2)
%       1748          2 B -   v[].a{}{}[].FA = 2:1x1:char
%       1744          4 B -   v[].a{}{}[].FA = 2:1x2:char
%       1544        200 B -   v[].a{}{}[].FB = 2:5x5:double
% CELL -----          0 B     v[].a{}{}[].FB = 2:0x0:cell
%       1544          0 B -   v[].b = 2:0x0:double
% CELL -----        152 B     v[].b = 2:1x2:cell
%       1544          0 B -   v[].b{} = 2:0x0:double
%       1512         32 B -   v[].b{} = 2:1x1:function_handle
于 2013-04-13T15:57:58.040 に答える