我有一个具有一些依赖属性的类,但我真的只想计算一次。
我刚刚得出结论,在MATLAB中对依赖类属性使用延迟求值要么不可能,要么是个坏主意。最初的计划是为每个需要更新的(公共)属性创建一个私有逻辑标志,并让构造函数将其设置为true。然后,当调用属性访问器时,它将检查该标志并计算该值并仅在需要时将其存储(在另一个私有属性中)。如果该标志为false,则只返回缓存值的副本。
我认为困难在于对属性访问者的限制,即他们只留下其他不相关的属性。换句话说,get.property(self)方法不能更改self对象的状态。有趣的是,这在我当前的课堂上无声地失败了。 (即,更新标志和缓存的计算结果都没有在get。方法中设置,因此每次都会运行昂贵的计算。)
我怀疑是将lazy属性从公共依赖属性更改为具有公共GetAccess但私有SetAccess的方法是可行的。但是,我不喜欢以这种方式欺骗财产惯例。我希望只有一个“懒惰”的属性可以为我做这一切。
我错过了一些明显的东西吗?是否禁止在MATLAB中依赖类属性的访问器方法来更改类实例的状态?如果是这样,那么定义具有私有副作用的访问者是什么,这是获得我想要的行为的最不邪恶的方式?
编辑:这是一个测试类......
classdef LazyTest
properties(Access = public)
% num to take factorial of
factoriand
end
properties(Access = public, Dependent)
factorial
end
properties(Access = private)
% logical flag
do_update_factorial
% old result
cached_factorial
end
methods
function self = LazyTest(factoriand)
self.factoriand = factoriand;
self.do_update_factorial = true;
end
end
methods
function result = get.factorial(self)
if self.do_update_factorial
self.cached_factorial = factorial(self.factoriand);
% pretend this is expensive
pause(0.5)
self.do_update_factorial = false
end
result = self.cached_factorial;
end
end
end
使用
运行它close all; clear classes; clc
t = LazyTest(3)
t.factorial
for num = 1:10
tic
t.factoriand = num
t.factorial
toc
end
继承自handle
后,时间大幅下降。
答案 0 :(得分:11)
我假设您正在使用值类。使用handle class(classdef myClass < handle
),通过引用传递,您可以轻松地在get方法中修改类。例如,我使用您建议的内容来从文件(如果尚未加载)或从私有隐藏属性加载数据。
请注意,使用lazy
依赖属性的方式与您提出的方法有所不同,这有点失败了使用依赖属性的目的,即保证您的数据始终与其派生的属性的状态保持同步从。每次更改其他属性时,您的懒惰属性都会过时。
您可以(应该)将set-method添加到将private属性设置为空的所有其他属性(isempty(obj.myPrivateProperty)
是“逻辑标志”,您需要知道是否必须计算)。但是,如果你这样做,为什么不让set-methods调用一些更新方法来立即更新/重新计算所有“依赖”属性?