是否可以在没有try块的情况下测试函数句柄?

And*_*lik 5 matlab function handle function-handle

有可能用不使用异常的东西替换下面的代码吗?手柄x是提供的手柄.我想在使用之前测试它的有效性(使用实际代码来支持句柄).

x = @notreallyafunction;
try
   x();
catch 
   disp('Sorry function does not exist.');
end
Run Code Online (Sandbox Code Playgroud)

cha*_*pjc 8

要测试函数句柄,例如筛选问题中的伪造x=@notreallyafunction,可以使用functions命令检查句柄并获取引用函数的名称,类型(简单,嵌套,重载,匿名等)和位置(如果是)在文件中定义.

>> x = @notreallyafunction;
>> functions(x)
ans = 
    function: 'notreallyafunction'
        type: 'simple'
        file: ''
>> x = @(y) y;
>> functions(x)
ans = 
     function: '@(y)y'
         type: 'anonymous'
         file: ''
    workspace: {[1x1 struct]}
>> 
Run Code Online (Sandbox Code Playgroud)

functions内置句柄(例如x=@round)的输出看起来就像一个虚假的函数句柄(type是'simple').下一步是测试存在的命名函数:

>> x = @round;
>> fx = functions(x)
fx = 
    function: 'round'
        type: 'simple'
        file: ''
>> exist(fx.function)
ans =
     5
>> x = @notreallyafunction;
>> fx = functions(x)
fx = 
    function: 'notreallyafunction'
        type: 'simple'
        file: ''
>> exist(fx.function)
ans =
     0
Run Code Online (Sandbox Code Playgroud)

但是,您需要处理匿名函数,因为它们无法存在测试:

>> x = @(y) y;
>> fx = functions(x)
>> exist(fx.function)
ans =
     0
Run Code Online (Sandbox Code Playgroud)

解决方案是先检查一下type.如果type是'anonymous',则检查通过.如果type是没有 'anonymous',他们可以依靠exist检查功能的有效性.总结一下,你可以创建一个这样的函数:

% isvalidhandle.m Test function handle for a validity.
%   For example,
%     h = @sum; isvalidhandle(h) % returns true for simple builtin
%     h = @fake; isvalidhandle(h) % returns false for fake simple
%     h = @isvalidhandle; isvalidhandle(h) % returns true for file-based
%     h = @(x)x; isvalidhandle(h) % returns true for anonymous function
%     h = 'round'; isvalidhandle(h) % returns true for real function name
%   Notes:  The logic is configured to be readable, not compact.
%           If a string refers to an anonymous fnc, it will fail, use handles.
function isvalid = isvalidhandle(h)

if ~(isa(h,'function_handle') || ischar(h)),
    isvalid = false;
    return;
end

if ischar(h)
    if any(exist(h) == [2 3 5 6]),
        isvalid = true;
        return;
    else
        isvalid = false;
        return;
    end
end

fh = functions(h);

if strcmpi(fh.type,'anonymous'),
    isvalid = true;
    return;
end

if any(exist(fh.function) == [2 3 5 6])
    isvalid = true;
else
    isvalid = false;
end
Run Code Online (Sandbox Code Playgroud)