在 Matlab 中,使用 PreSet 侦听器时传递新变量的正确语法是什么
In Matlab, what is the correct syntax for passing new variables when using a PreSet listener
我正在编写一个 class 定义,它在设置某些属性时使用侦听器修改对象。像这样:
classdef MyObject < handle
properties (SetObservable)
orientation = 'h'; % h = horizontal, v = vertical, o = other
length
width
end
methods
% Constructor
function mo = MyObject(o)
mo.orientation = o;
addlistener(mo, 'orientation', 'PreSet', @mo.changeOrientation);
end
% Change Orientation Listener
function changeOrientation(mo, src, evnt)
celldisp(src);
celldisp(evnt);
% I want a way to access newor here
if mo.orientation == 'h' && newor == 'o'
tempw = mo.width
mo.width = mo.length
mo.length = tempw;
end
end
% Setter
function set.orientation(mo, newor)
mo.orientation = newor;
end
end
end
我希望在设置方向时能够使用变量 newor。如何将新方向变量传递给 changeOrientation 方法?
我想避免将 changeOrientation
的内容移动到 set.orientation
方法中,因为 Matlab 抱怨属性(长度和宽度)可能未被初始化。
编辑
长度不依赖于方向。我只需要在方向改变时交换长度和宽度。在其他情况下,用户应该能够将长度或宽度设置为任何正值。
您不能这样做,因为 PreSet 侦听器 只是 ,一个侦听器。传递给侦听器回调的数据永远不会返回到对象,并且在侦听器中修改它的值没有任何影响。
使用PreSet listener的目的是在属性改变之前获取属性的值,而不是在实际赋值之前修改任何值.
在您发布的代码中,我可能会在您的 class 的 set.orientation
方法中执行任何 validation/modification 方向。
function updateLength(mo)
% Change mo.length here and others based on mo.orientation
end
function set.orientation(mo, newor)
% validate newor
if dovalidation(newor)
mo.orientation = newor;
else
error('invalid!');
end
% Now trigger a "callback"
mo.updateDependentVariables()
end
编辑
根据您的评论,解决此问题的更好方法可能是让 length
有一个影子 属性 length_
来保存用户分配给 [=13 的值=].当用户请求 length
的值时,它可以 return 这个存储的值(如果 orientation == 'v')或者 width
(如果 orientation == 'h')
classdef MyObject
properties (Dependent)
length % Can be either `width_` or `length_`
width % Can be either `width_` or `length_`
end
properties
orientation
end
properties (Access = 'protected')
length_ = 12
width_ = 10
end
methods
function mo = MyObject(o)
mo.orientation = o;
end
function set.orientation(mo, newor)
% If the user supplies an "o" flip the orientation
if strcmpi(newor, 'o')
if strcmpi(mo.orientation, 'v')
newor = 'h';
else
newor = 'v';
end
end
mo.orientation = newor;
end
function set.length(mo, value)
if strcmpi(mo.orientation, 'h')
self.length_ = value;
else
self.width_ = value;
end
end
function set.width(mo, value)
if strcmpi(mo.orientation, 'h')
self.width_ = value;
else
self.length_ = value;
end
end
function res = get.width(mo)
switch lower(mo.orientation)
case 'h'
res = mo.width_;
case 'v'
res = mo.length_;
otherwise
error('Invalid orientation');
end
end
function res = get.length(mo)
switch lower(mo.orientation)
case 'h'
res = mo.length_;
case 'v'
res = mo.width_;
otherwise
error('Invalid orientation');
end
end
end
end
这样您就不必在更改方向时显式更新 length
。
作为旁注,我 不会 将 length
用作 属性,因为这与内置函数 length
.
你不需要额外的监听器。这就是自定义 setter / getter 方法的用途。在您的示例中使用 set.orientation
方法毫无意义,除了无论如何都会发生的赋值之外,它什么都不做。相反,使用此方法额外调用 changeOrientation
:
classdef MyObject < handle
properties (SetObservable)
orientation = 'h'; % h = horizontal, v = vertical
end
methods
% Constructor
function mo = MyObject(o)
mo.orientation = o;
end
% Change Orientation Listener
function changeOrientation(mo, newor)
% Use newor here!
end
% Setter
function set.orientation(mo, newor)
mo.changeOrientation(newor);
mo.orientation = newor;
end
end
end
我正在编写一个 class 定义,它在设置某些属性时使用侦听器修改对象。像这样:
classdef MyObject < handle
properties (SetObservable)
orientation = 'h'; % h = horizontal, v = vertical, o = other
length
width
end
methods
% Constructor
function mo = MyObject(o)
mo.orientation = o;
addlistener(mo, 'orientation', 'PreSet', @mo.changeOrientation);
end
% Change Orientation Listener
function changeOrientation(mo, src, evnt)
celldisp(src);
celldisp(evnt);
% I want a way to access newor here
if mo.orientation == 'h' && newor == 'o'
tempw = mo.width
mo.width = mo.length
mo.length = tempw;
end
end
% Setter
function set.orientation(mo, newor)
mo.orientation = newor;
end
end
end
我希望在设置方向时能够使用变量 newor。如何将新方向变量传递给 changeOrientation 方法?
我想避免将 changeOrientation
的内容移动到 set.orientation
方法中,因为 Matlab 抱怨属性(长度和宽度)可能未被初始化。
编辑 长度不依赖于方向。我只需要在方向改变时交换长度和宽度。在其他情况下,用户应该能够将长度或宽度设置为任何正值。
您不能这样做,因为 PreSet 侦听器 只是 ,一个侦听器。传递给侦听器回调的数据永远不会返回到对象,并且在侦听器中修改它的值没有任何影响。
使用PreSet listener的目的是在属性改变之前获取属性的值,而不是在实际赋值之前修改任何值.
在您发布的代码中,我可能会在您的 class 的 set.orientation
方法中执行任何 validation/modification 方向。
function updateLength(mo)
% Change mo.length here and others based on mo.orientation
end
function set.orientation(mo, newor)
% validate newor
if dovalidation(newor)
mo.orientation = newor;
else
error('invalid!');
end
% Now trigger a "callback"
mo.updateDependentVariables()
end
编辑
根据您的评论,解决此问题的更好方法可能是让 length
有一个影子 属性 length_
来保存用户分配给 [=13 的值=].当用户请求 length
的值时,它可以 return 这个存储的值(如果 orientation == 'v')或者 width
(如果 orientation == 'h')
classdef MyObject
properties (Dependent)
length % Can be either `width_` or `length_`
width % Can be either `width_` or `length_`
end
properties
orientation
end
properties (Access = 'protected')
length_ = 12
width_ = 10
end
methods
function mo = MyObject(o)
mo.orientation = o;
end
function set.orientation(mo, newor)
% If the user supplies an "o" flip the orientation
if strcmpi(newor, 'o')
if strcmpi(mo.orientation, 'v')
newor = 'h';
else
newor = 'v';
end
end
mo.orientation = newor;
end
function set.length(mo, value)
if strcmpi(mo.orientation, 'h')
self.length_ = value;
else
self.width_ = value;
end
end
function set.width(mo, value)
if strcmpi(mo.orientation, 'h')
self.width_ = value;
else
self.length_ = value;
end
end
function res = get.width(mo)
switch lower(mo.orientation)
case 'h'
res = mo.width_;
case 'v'
res = mo.length_;
otherwise
error('Invalid orientation');
end
end
function res = get.length(mo)
switch lower(mo.orientation)
case 'h'
res = mo.length_;
case 'v'
res = mo.width_;
otherwise
error('Invalid orientation');
end
end
end
end
这样您就不必在更改方向时显式更新 length
。
作为旁注,我 不会 将 length
用作 属性,因为这与内置函数 length
.
你不需要额外的监听器。这就是自定义 setter / getter 方法的用途。在您的示例中使用 set.orientation
方法毫无意义,除了无论如何都会发生的赋值之外,它什么都不做。相反,使用此方法额外调用 changeOrientation
:
classdef MyObject < handle
properties (SetObservable)
orientation = 'h'; % h = horizontal, v = vertical
end
methods
% Constructor
function mo = MyObject(o)
mo.orientation = o;
end
% Change Orientation Listener
function changeOrientation(mo, newor)
% Use newor here!
end
% Setter
function set.orientation(mo, newor)
mo.changeOrientation(newor);
mo.orientation = newor;
end
end
end