【问题标题】:Function handle to a method in a constant property常量属性中方法的函数句柄
【发布时间】:2018-10-17 20:30:34
【问题描述】:

在 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

【问题讨论】:

    标签: matlab oop anonymous-function handle


    【解决方案1】:

    根据@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!
    

    【讨论】:

    • 很好的答案!虽然奇怪的限制......并没有让事情更直观恕我直言......而且你必须写笨拙的@(varargin)obj.instance.SomeMethod(varargin{:})只是为了得到一些论点......哪种迫使你使用中间人。哦,好吧,我们是used to that from MATLAB?
    • @Rody:您可以考虑将此作为错误提交给 MahWorks。我同意这没什么意义。
    • 是的,我想我应该。你在哪个版本上试过这个?
    • @Rody:我用的是 R2018b。
    【解决方案2】:

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

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

    我倾向于这是对 function handle operator 工作方式的限制,而不是 MATLAB 类系统。

    【讨论】:

    • 我同意,是@操作符做了意想不到的事情,与类系统无关。
    猜你喜欢
    • 2022-01-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-14
    • 1970-01-01
    相关资源
    最近更新 更多