ger*_*rit 7 matlab stack namespaces function-handle matlab-class
我有一个缓存评估功能.作为参数之一,它需要一个函数句柄.在某些情况下,函数句柄是不可访问的,我不太明白为什么.下面的例子显示了让我难过的原因:
>> A.a = @plus; feval(@A.a, 1, 1)
ans =
2
>> clear A
>> A.a.a = @plus; feval(@A.a.a, 1, 1)
Error using feval
Undefined function 'A.a.a' for input arguments of type 'double'.
Run Code Online (Sandbox Code Playgroud)
因此,如果我将一个函数句柄存储为一个结构成员,如果它是一个深度,我可以传递它,但如果它是两个级别深,则不能.在我的实际使用情况下,我有一个结构D保存各种类别的许多(117)的情况下,所以其实我有stct.obj.meth,这里stct是一个结构,obj是一个类的实例/对象,meth是一种方法.传递@stct.obj.meth失败,但如果我分配A = stct.obj,则传递@A.meth成功.
在什么条件下我可以将函数句柄作为参数传递,以便它仍然可以在堆栈中访问?
编辑:虽然在上面的用例中,我可以简单地删除@因为@plus已经是一个函数句柄.但是,请考虑以下情况:
>> type cltest.m
classdef cltest < handle
methods
function C = mymeth(self, a, b)
C = a + b;
end
end
end
>> A.a = cltest();
>> feval(@A.a.mymeth, 1, 1)
Error using feval
Undefined function 'A.a.mymeth' for input arguments of type 'double'.
>> b = A.a;
>> feval(@b.mymeth, 1, 1)
ans =
2
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我需要的@前A.a.mymeth...
介绍类对MATLAB来说是一个大问题.事实上,这么大,他们今天仍然无法正常工作.您的示例显示结构访问和类方法访问冲突,因为它们必须重载点'.'的含义.并没有让它无缝地工作.当您在MATLAB控制台上通过名称显式调用类方法时,或多或少都可以正常工作,例如在您的示例>> Aamymeth(1,1)中.但是当你有任何类型的间接时,它很快就会破裂.
您尝试获取函数句柄>> @A.a.mymeth,MATLAB无法理解,可能是因为它被混合结构/类事物混淆了.尝试使用str2func也不起作用.它的工作原理,再一次,只为明确的名称访问,如图所示这里.它打破了你的榜样,例如>> str2func('b.mymeth').它甚至不在课堂上工作.尝试其他方向并观察它们失败.
另外,MATLAB不喜欢给你一个类方法的句柄.它没有任何功能.无法一次性获取所有函数句柄,甚至无法通过名称字符串动态获取所有函数句柄.
我在这里看到三种选择.首先,如果可能的话,尝试更改您的程序.这些功能是否需要坐在classdef中?
其次,请遵循您的或nispio的解决方法.它们都创建一个临时变量来保存对类实例的引用,以便创建对其成员方法的非混合访问.问题是,它们都需要明确命名函数.您必须为所涉及的每个函数明确地放置此代码.没办法把它抽象出来.
第三,通过从内部发出你的班级方法句柄作弊.你可以把它们放在一个结构中.
classdef cltest < handle
methods
function C = mymeth(self, a, b)
C = a + b;
end
function hs = funhandles(self)
hs = struct('mymeth', @self.mymeth, ...
'mymeth2', @self.mymeth2);
end
end
end
Run Code Online (Sandbox Code Playgroud)
然后,您可以按名称访问句柄,甚至可以动态访问.
>> A.a = cltest;
>> feval(A.a.funhandles.mymeth, 1, 1);
>> feval(A.a.funhandles.('mymeth'), 1, 1)
ans =
2
Run Code Online (Sandbox Code Playgroud)
但要小心,通过使用它,您可以从外部访问Access = private方法.