您可以使用函数句柄调用对象的方法。例:
classdef foo
methods
function value=foofun(this)
value=1;
end
end
end
然后
fun=@foofun;
fun(foo);
我猜句柄只是一个字符串,在使用句柄之前它无法分辨出哪个函数是哪个函数,这不会打扰 Matlab。如果使用不同类型的对象作为第一个参数,则甚至可以使用相同的句柄来调用不同的方法。
要捕获函数的输出,您可以执行以下操作:
outputs=cell(numberOfOutputs,1);
[outputs{:}]=fun(foo);
但是,如果函数句柄是代码中的参数,则输出的数量是一个问题。对于普通函数的句柄,nargout 可以解决这个问题,但现在 nargout 无济于事,因为句柄不能自行确定将调用哪个函数。Nargout需要第二个输入,即将使用的对象类型。
需要句柄和输出数量作为参数有点不优雅。有没有另一种方法可以间接调用方法并仍然捕获所有输出?
用例
想象一个带有节点和节点之间边缘的图形。每个边都有一些与该特定边关联的数据对象。我对对这些数据对象进行各种计算感兴趣。
例子
- 获取与特定边缘关联的所有数据对象,并计算这些对象的光谱。
- 使用每个边缘中最漂亮的数据对象,并从这些对象获取光谱。 随机选择十条边,
- 从每条边中随机选择一个数据对象,然后将这些对象与特定的单独对象进行比较。
设计
这个想法是将对象的选择和计算分离到不同的函数中。这样,用户可以将任何计算与任何选择方法相结合。每次向数据对象添加新方法时,都可以使用现有的对象选择方法调用该方法,并且每次添加新的选择方法时,都可以将其与所有可用的计算方法一起使用。
我当前使用的函数的简化版本如下所示
function [ outs ] = callForEach(objects, fun, numberOfOutputs, extraArguments)
for ii=1:length(objects)
out=cell(1,numberOfOutputs);
[out{:}]=fun(objects{ii},extraArguments{ii,:});
outs(ii,:)=out;
end
end
我希望能够避免参数编号输出。这对用户来说是一种不便,而且这样做更容易出错。
我想我可以为每个方法强制使用相同的接口:如果他们需要多个输出,每个人都返回一个单元格数组。然后,我可以将该单元格数组或返回的任何内容分配给单个单元格。但是,所有内置函数似乎都更喜欢使用多个输出,因此至少存在风格差异。如果我想使用其中一个内置函数作为句柄,我需要编写一个包装器来使内置函数符合接口。
检查此类是否foo.m
。通过运行foo.main()
您可以恢复大多数已解决的问题。
这不是 OOP 中最大的优雅,但你有 Matlab。
请记住,obj
变量是必需的,输入和输出。没有obj
,没有点幻想。
最后的调用,必须包括f1
。放置~
不仅会失去幻想,还会丢失对象及其数据。
除了obj
治疗外,nargin
|nargout
|varargin
|varargout
仅在函数体内有效,并且像往常一样依赖于运行时。一般无法知道您将抛出多少参数,因为它相当于 varargout 细胞的长度。
classdef foo
properties
value;
end
methods
function [obj,flag]=fun1(obj,this)
obj.value=this+1;
flag=1;
end
function [obj,flag]=fun2(obj,this)
obj.value=2*this;
flag=2;
end
function [obj,varargout]=fun3(obj,varargin)
for i=1:nargin-1
varargout{i}=varargin{i};
end
obj.value=0;
end
end
methods (Static)
function main()
if 0
%% Run this line
foo.main()
end
f1=foo();
[f1,flag]=f1.fun1(10);
flag
f1.value
f=@fun2;
%[f1,flag]=f1.f(10); % fails
flag
f1.value
[f1,flag]=f1.('fun2')(10);
flag
f1.value
[~,flag]=f1.fun2(10); % fails
flag
f1.value
[f1,a1,a2,a3,a4]=f1.fun3('x1',2,[],@(x)(x>1))
end
end
end