【问题标题】:How can I validate a function handle as an input argument?如何验证函数句柄作为输入参数?
【发布时间】:2013-10-01 13:51:11
【问题描述】:

我有一个类,它有一个函数句柄作为其properties 之一。

classdef MyClass
    properties
        hfun %function handle 
    end

    methods
        function obj = Myclass(hfun,...)
            %PROBLEM: validate that the input argument hfun is the right kind of function
            if ~isa(hfun,'function_handle') || nargin(hfun)~=1 || nargout(hfun)~=1
                error('hfun must be a function handle with 1 input and 1 output');
            end
            obj.hfun = hfun;
        end
    end
end

我想确保输入参数hfun 是一个具有 1 个输入和 1 个输出的函数句柄,否则它应该会出错。如果我能更具体一点,我希望这个函数将 Nx3 数组作为输入参数并返回一个 Nx3 数组作为输出参数。

上面的代码适用于像f = @sqrt 这样的内置函数,但是如果我尝试放入像f = @(x) x^(0.5) 这样的匿名函数,那么nargout(hfun) 是-1,因为它将匿名函数视为[varargout] = f(x)。此外,如果您将句柄输入到像f = @obj.methodFun 这样的类方法,那么它会将函数转换为[varargout] = f(varargin) 的形式,对于narginnargout 都返回-1。

有没有人想出一种方便的方法来验证函数句柄作为输入参数?与它来自哪种函数句柄无关?

【问题讨论】:

  • 您可以使用functions 函数来提取有关函数句柄的更多信息。 mathworks.se/help/matlab/ref/functions.html
  • 这样做有什么实际用途?
  • 我想将它用于几个用途。我正在编写一个 A* 类,它计算节点边图上的最短路径,但我想让用户能够自定义启发式函数,而不仅仅是使用到目标的默认欧几里得距离。另一个用途是在我的 RRT 类中,它实现了快速探索随机树算法来构建节点边图。我想让用户能够自定义节点扩展的运动约束。用户将能够将此运动约束作为函数句柄输入。

标签: matlab oop validation matlab-class function-handle


【解决方案1】:

我最接近验证函数句柄的输入和输出的方法是在 try/catch 语句中。

function bool = validateFunctionHandle(fn)
    %pass an example input into the function
    in = blahBlah; %exampleInput
    try
        out = fn(in);
    catch err
        err
        bool = false;
        return;
    end

    %check the output argument
    if size(out)==correctSize and class(out)==correctType
        bool=true;
    else
        bool=false;
    end
end

【讨论】:

    【解决方案2】:

    您可以使用class 来判断变量是否是函数句柄,但是没有简单的方法来验证输入和输出的类型,因为 MATLAB 是松散类型的,并且变量可以包含任何内容,只要它可以弄清楚如何在运行时解释命令。正如 Mohsen 所指出的,您还可以使用函数来获取更多信息,但这对您没有太大帮助。

    这是我认为你能得到的最接近的:

    fn = @(x,y) x + x*2
    
    if strcmpi(class(fn), 'function_handle')
        functionInfo = functions(fn)
        numInputs =  nargin(fn)
        numOutputs = nargout(fn)
    end
    

    如果速度不是问题,您可以创建一个类,其中包含运行该函数的成员函数run 和返回您需要的任何详细信息的geInfo。然后,您总是将一个类传递给您的函数,该函数将内置信息。但是,这将是缓慢且不方便的。

    【讨论】:

    • 我可以使用isa(fn,'function_handle') 来检测它是否是函数句柄,但narginnargout 是可变的,具体取决于函数是否为内置、类方法、匿名等。@ 987654328@ 命令给出了名称、类型和文件,但没有说明输入/输出参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多