Matlab:有关句柄变量和 mat 文件的文档?

Matlab: Documentation on handle variables and mat files?

是否有关于在保存和加载 mat 文件时如何处理句柄变量的任何 TMW 文档?通过反复试验,我确定了基本行为,例如,底层对象存储到 mat 文件,并从 mat 文件加载,但实际的 class 定义本身不是。也就是说,如果您加载了一个句柄对象,但是您的 class 定义已通过添加字段进行了修改,则加载的对象将具有这些附加字段,尽管它们不会使用值进行初始化。

对于那些在面向对象编程中定义句柄 classes 的人来说,更全面的设计行为文档是必不可少的。例如,如果你将对象 A 保存到一个 mat 文件中,并且它有一个引用对象 Z 的 属性,那么你将对象 B 保存到一个 mat 文件中,它还包含一个 属性指的是对象 Z?如果我加载两个 mat 文件中的每一个,我是否会有对象 Z 的两个单独实例,或者这两个变量是否会引用同一个对象?

另一种情况可能是两个句柄对象变量引用同一个对象,但一个变量在基础工作区中,另一个变量实际上是另一个对象的属性?如果我保存并加载,这两个变量是否仍然指向同一个对象?

我知道我可以根据经验对每个可能的场景进行逆向工程,但它比阅读行为规范(如果存在)效率低得多。

Matlab 句柄对象只要在内存中就通过引用传递。但是,当它们被保存并重新加载时,它们是一个新对象,因此,对它们的任何引用都是 "broken"(请参见下面的示例)。这对于 class 句柄的所有对象都是正确的,无论您构造的案例有多复杂(例如 objectAobjectB 的 属性 又是 属性 的 objectA 会在重新加载后突然占用更多内存):从磁盘加载对象会创建一个新的、未引用的实例。

objA = myHandleObject();
objB = objA; %# same object, changing A changes B
save('objOnDisk.mat','objB');
load('objOnDisk.mat') %# overwrites objB in the workspace
%# objB is no longer a reference of objA

如果您修改句柄对象,例如集群上的 parfor 循环,因为工作空间被保存并重新加载到各个工作人员上。

有一种解决方法:您可以定义 loadobj 函数来查找相同 class 的其他对象,如果您为每个对象添加一个唯一的参考编号(设置一个 属性 到 tempname,例如),您可以手动 "rebuild" 引用。去过那里,做过,但不推荐,因为它变得非常复杂,很快。

我要感谢受访者。他们的回答非常有帮助。但是,问题是句柄对象变量的 save/load 行为是否被记录在案。答案似乎是 "no",我会问 TMW 他们是否觉得值得记录这个。

进一步了解 Jonas 关于 save/load 行为的信息,我创建了以下测试以确定在 (i) 加载整个工作区与 (ii) 单个句柄对象变量时加载行为的差异。正如我在评论中推测的那样,同一对象的多个句柄在情况 (i) 中保持对公共对象的引用,但在情况 (ii) 中它们引用单独的(但相同的)对象:

% myClassA.m
%-----------
% Handle class
classdef myClassA < handle
properties
   myPropA
end % properties
end % classdef

% myClassB.m
%-----------
% The property will refer to a
% handle class object
classdef myClassB
properties
   myObjA
end % properties
end % classdef

% test.m
%--------
% Main test script, uses the two
% classes
clc
echo on

% Create 2 object variables. 2nd
% one has a property that refers to
% same object as the first one
objA = myClassA
objA.myPropA = 5
objB = myClassB
objB.myObjA = objA

% Check that changes in handle object
% is seen from both variables
objA.myPropA = 7
objB.myObjA.myPropA % Should be 7

% Save & load entire workspace.
% Check that both variables refer
% to same object.
save('myWrkSpc')
clear classes
load('myWrkSpc')
objA
objB.myObjA
objA.myPropA = 9
objB.myObjA % Should be 9

% Load variables individually. Show
% that they now refer to separate
% objects
clear classes
load('myWrkSpc','objA')
load('myWrkSpc','objB')
objA
objB.myObjA
objA.myPropA = 9
objB.myObjA
   % Should still be 7 instead of 9

echo off

这些是我迄今为止遇到的场景,不过我确定我会 运行 进入新的场景,在这些场景中对设计行为进行全面记录会有所帮助。