您基本上希望赋值 ( DS1.mod.Q = value
) 具有副作用,这不可避免地意味着一个 setter,因此是一个类。你应该要么放弃这个要求,要么写一个类。
如果您希望避免在类声明中定义属性,则可以使用Dynamic Properties,它允许您在运行时添加属性(尽管有一些说明性的语法addprop()
)。
编辑
帕特里克,问题比 M-lint 更深。考虑以下类:
classdef cantInstantiateMe < handle
properties
x
minus_x
end
methods
function obj = cantInstantiateMe(x)
obj.x = x; % <-- this calls set.x(), which calls set.minus_x(), which calls set.x(), ...
obj.minus_x = -x;
end
function set.x(obj, value)
obj.x = value;
obj.minus_x = -value; % <-- this gives an M-Lint warning
end
function set.minus_x(obj, value)
obj.minus_x = value;
obj.x = -value;
end
end
end
这个类不能被实例化,因为每个 setter 调用另一个 setter(这不是 Matlab 特定的)。尝试在我的机器上实例化给出:
???达到最大递归限制 500。使用 set(0,'RecursionLimit',N) 更改限制。请注意,超出可用堆栈空间可能会使 MATLAB 和/或您的计算机崩溃。
在这一点上,我认为你有两个选择:
- 制作 要么
Q
要么Qchol
附属财产. 这将以每次读取访问时重新计算从属属性为代价。
使用一些私有影子属性,例如shadow_Q
,shadow_Qchol
它们将在调用公共属性的 setter 时设置,并在调用它们的 getter 时返回。如同:
function set.x(obj, value)
obj.shadow_x = value;
obj.shadow_minus_x = -value;
end
function value = get.x(obj)
value = obj.shadow_x;
end
请注意,我没有正确测试这个,所以我不知道 Matlab 中的所有含义。在我熟悉的其他语言中,这应该可以正常工作。
- 关于警告 - 我的方法是禁用警告是安全的,只要你真的知道你在做什么。