matlab 需要类通过句柄公开私有静态函数

qqrboqgw  于 8个月前  发布在  Matlab
关注(0)|答案(1)|浏览(119)

我需要一个特定的类来公开一个私有静态函数。我通过一个存储在单元数组中的匿名函数来实现这一点。下面这个人为的例子说明了这个问题:

classdef ParamClass
    properties (Constant)
        param_spec = {
            {'param_1', @(x) isnumeric(x) && isscalar(x) && (x > 0)}, ...
            {'param_2', @(x) ParamClass.validate_param_2(x)} ...
            };
    end
    
    properties
        param_1;
        param_2;
    end
    
    methods (Static, Access = 'private')
        function ok = validate_param_2(x)
            ok = isnumeric(x) && isscalar(x) && (x  < 0);
        end 
    end
    
    methods
        function obj = ParamClass(p1, p2)
            opts = parse_my_args(p1, p2, ParamClass.param_spec{:});
            obj.param_1 = opts.param_1;
            obj.param_2 = opts.param_2;
        end
    end
end

function opts = parse_my_args(p1, p2, varargin)
    assert(varargin{1}{2}(p1));
    assert(varargin{2}{2}(p2));
    
    opts.param_1 = p1;
    opts.param_2 = p2;
end

函数ParamClass.validate_param_2是私有静态的,但我希望它通过匿名函数 Package 器被外部独立函数调用。但我得到以下错误:
使用ParamClass.validate_param_2时出错
无法访问类“ParamClass”中的方法“validate_param_2”。
经过一番思考,这个错误似乎是不必要的。类向外部传递函数句柄。句柄的内容应该只由类来决定,而不应该是任何人的事。validate_param_2所需的所有上下文不都应该是匿名函数的一部分吗?当然,我可以通过公开validate_param_2来删除这个错误,但是我想了解这个错误背后的原理。
任何解释为什么需要这种错误的意见将不胜感激。还有其他选择吗?

p3rjfoxz

p3rjfoxz1#

这确实是一个奇怪的错误,我认为它没有多大意义。一种解释可能是,当属性约束被评估时,类定义在内存中还没有完成,函数ParamClass.validate_param_2()还不可用。但同样,没有理由这样做,它可能不是一个有意识的选择(即。这是一个bug)。
作为替代,您可以使用a local function(即在同一个文件中的classdef块之后定义的函数)。这样的函数只能从文件中看到,但是你可以返回一个句柄,使它可以从另一个文件中使用。这个局部函数也可以访问类的私有成员。对于所有的意图和目的,它是一个私有成员,除了它只能从@ParamClass目录中定义的文件类方法中看到它。

classdef ParamClass
    properties (Constant)
        param_spec = {
            {'param_1', @(x) isnumeric(x) && isscalar(x) && (x > 0)}, ...
            {'param_2', @validate_param_2} ...
            };
    end
    
    properties
        param_1;
        param_2;
    end
    
    methods
        function obj = ParamClass(p1, p2)
            opts = parse_my_args(p1, p2, ParamClass.param_spec{:});
            obj.param_1 = opts.param_1;
            obj.param_2 = opts.param_2;
        end
    end
end

function opts = parse_my_args(p1, p2, varargin)
    assert(varargin{1}{2}(p1));
    assert(varargin{2}{2}(p2));
    
    opts.param_1 = p1;
    opts.param_2 = p2;
end

function ok = validate_param_2(x)
    ok = isnumeric(x) && isscalar(x) && (x < 0);
end

相关问题