我有一个类以一种奇怪的方式封装对数组的访问; 类构造函数接受一个函数句柄,它是在将索引传递给数组
之前对索引进行某种转换classdef MyClass
properties
arr
accessHandle
end
methods
function obj = MyClass(array, trans)
obj.arr = array;
obj.accessHandle = @(i) obj.arr(trans(i))
end
end
问题是匿名函数将数组复制到它自己的工作区中,如果我们更改数组,它就不会在函数中发生变化。 基本上所需要的是将匿名函数传递给'这个'指针/引用,如Java / C ++ / etc
简单的解决方案是创建数组的句柄并将其传递给函数:
classdef MyClass
properties
arr
accessHandle
end
methods
function obj = MyClass(array, trans)
obj.arr = array;
tmp = PropertyReference(obj, 'arr'); %See http://stackoverflow.com/questions/7085588/matlab-create-reference-handle-to-variable
%for the definition
obj.accessHandle = @(i) tmp(trans(i));
end
end
end
现在的问题是当我将类的实例传递给函数时,传递的引用仍然引用函数外部的对象:
function foo(ins)
ins.arr = [1 2];
disp(ins.accessHandle(1));
end
cl = MyClass([0 3], @(x) x);
foo(cl) //output 0 instead of 1
disp(ins.accessHandle(1)) //output 0
编辑:该类应该是一个值类,语义是当创建类的副本时,accessHandle
字段会更改它使用的数组句柄。
如何实现正确的语义?
答案 0 :(得分:2)
目前,您的类是一个值类(MATLAB的默认值)。如果您希望能够通过引用传递对象(更改将反映在原始对象中),您可以通过继承handle
classdef MyClass < handle
properties
arr
accessHandle
end
methods
function obj = MyClass(array, trans)
obj.arr = array;
obj.accessHandle = @(i) obj.arr(trans(i))
end
end
end
然后你可以按照预期的方式使用它
m = MyClass([1 2 3], @(x)x);
m.accessHandle(2)
% 2
m.arr(2) = 5;
m.accessHandle(2)
% 5
有关两个can be found here之间差异的更多信息。
修改强>
如果您需要MyClass
作为值类,那么您可以将trans
值存储为属性,然后使用常规方法来访问该值
classdef MyClass
properties
arr
trans
end
methods
function obj = MyClass(array, trans)
obj.arr = array;
obj.trans = trans;
end
function res = access(obj, k)
res = obj.arr(obj.trans(k));
end
end
end
或者,如果您愿意,可以使accessHandle
为依赖属性,返回函数句柄。
classdef MyClass
properties
arr
trans
end
properties (Dependent)
accessHandle
end
methods
function obj = MyClass(array, trans)
obj.arr = array;
obj.trans = trans;
end
function res = get.accessHandle(obj)
res = @(i)obj.arr(obj.trans(i));
end
end
end