常量 属性 中方法的函数句柄

Function handle to a method in a constant property

在 R2018b 中,我有以下设置:

classdef SomeClass < handle    
    methods
        function SomeMethod(obj)
            disp in!
        end
    end    
end

classdef SomeOtherClass < handle

    properties (Constant)
        instance = SomeClass()
    end

    methods
        function Test(obj)
            hdl = @obj.instance.SomeMethod;
            hdl();            
        end
    end

end

但是运行Test()方法报错:

>> SomeOtherClass().Test() 
Undefined function or variable 'obj.instance.SomeMethod'.

Test() 方法更改为:

function Test(obj)
    A   = obj.instance;
    hdl = @A.SomeMethod;
    hdl();
end

给出了想要的结果:

>> SomeOtherClass().Test
in!

我很困惑...为什么我需要中间人A

我还没有完整的答案,但这里有一些值得深思的地方:您可以使用 structure 代替 SomeOtherClass 来重新创建相同的结果:

>> obj = struct('instance', SomeClass());
>> hdl = @obj.instance.SomeMethod;
>> hdl()
Undefined function or variable 'obj.instance.SomeMethod'.

我倾向于这是 function handle operator 相对于 MATLAB class 系统的工作方式的限制。

根据@gnovice 的发现:

>> obj = struct('instance', SomeClass());
>> hdl = @obj.instance.SomeMethod
hdl =
  function_handle with value:
    @obj.instance.SomeMethod

>> hdl(obj.instance)
Undefined function or variable 'obj.instance.SomeMethod'.

>> hdl()
Undefined function or variable 'obj.instance.SomeMethod'.

但是:

>> instance=SomeClass();
>> hdl = @instance.SomeMethod
hdl =
  function_handle with value:
    @(varargin)instance.SomeMethod(varargin{:})

>> hdl(instance)
Error using SomeClass/SomeMethod
Too many input arguments.

Error in @(varargin)instance.SomeMethod(varargin{:})

>> hdl()
in!

请注意在第二种情况下创建的函数句柄实际上是一个匿名函数,其中包含对象。这是 @ 运算符的特例,不是正常用法,它是:

>> hdl=@SomeMethod
hdl =
  function_handle with value:
    @SomeMethod

>> hdl(instance)
in!

这个案例实际上做的是创建一个匿名函数,它嵌入了你打算调用这个方法的对象。您可以这样创建这样的函数:

>> hdl=@()obj.instance.SomeMethod()
hdl =
  function_handle with value:
    @()obj.instance.SomeMethod()

>> hdl()
in!