評論
是否有可能爲你從使用結構的一類切換?如果是這樣,你可以創建一個模仿結構的模塊,並且每次修改時調用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
覆蓋是這裏的關鍵點,使得它像一個結構(通過推遲所有的一個實際的結構活動),但其他類似的覆蓋和fieldnames
做disp
同樣的事情。在subsasgn
中,保存了結構的所有賦值的記錄以及生成賦值的堆棧。
注意:爲了完全兼容內置的struct
你可能應該重寫一些更多的方法,但這應該足以讓你開始。見Subclassing MATLAB Built-In Types。
編輯:我讓這個例子更健壯一些。它現在是一個價值類 - 它應該是 - 並且與串聯一起工作。
編輯:可避免使用查找和替換通過重新定義功能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
)。
你可以通過與「字段名」命令的結構的所有級別遞歸去。 – tashuhka
@tashuhka但我想獲得結構產生的原始命令,而不需要重新輸入內容。對於我來說,用一個非常大的結構來做它是沒有彈性的,這個命令會對測試有很大的幫助。必須有一些命令來做到這一點。 – hhh
輸入'a =',然後在鍵盤上按下。控制檯會找到以'a ='開頭的最後一行。除非你在談論你沒有產生的結構。在這種情況下,我認爲這是不可能的... – wakjah