我什么时候可以传递一个文字:一个函数?

ger*_*rit 11 syntax matlab slice

在什么情况下我可以将文字:传递给Matlab函数?我通过实验发现,有时,文字:作为字符串传递':',但在其他情况下,会引发错误.例如:

>> type writeargs

function writeargs(varargin)

disp(varargin);

end

>> writeargs(:)
Undefined variable writeargs.

>> writeargs(:, 1)
Undefined variable writeargs.

>> writeargs(:, 1, :)
    ':'    [1]    ':'

>> writeargs(:, :, :)
    ':'    ':'    ':'

>> writeargs(1, 2, :, 4, 5)
    [1]    [2]    ':'    [4]    [5]

>> writeargs(1, 2, :, end)
Error using writeargs
Too many output arguments.
Run Code Online (Sandbox Code Playgroud)

我的印象是,如果传递至少三个参数,则允许使用此语法.这似乎是武断的.这里的法律语法是什么?

编辑:评论要求用例.用例可以是我的参数将被用作切片或索引.在Python代码中,我遇到了将切片对象传递给方法的情况.一个用例是针对一个函数,例如受到这个答案的启发,其中一个小函数用于绕过Matlabs无法解释magic(5)(3, :),并且可以编写辅助函数并调用它paren(magic(5), 3, :).

Ale*_*lex 2

您不应该将文字 : 传递给函数。冒号用于索引仅直接适用于变量(请参阅此处此处)。冒号不是真实的对象,也没有类型。如果您打算将它用作函数参数,则它需要是一个类型化对象。当然,函数调用和变量索引具有相同的语法可能会令人困惑。但是,如果您要求使用冒号作为函数参数的合法语法,则没有。

话虽如此,正如您所观察到的,它在某些情况下仍然有效。这是由于 MATLAB 采取了一些预处理步骤,并且只有 MathWorks 可以处理。当您给它三个或更多参数(或两个参数,都是冒号)时,MATLAB 似乎通过类似 subsref 的预处理来调用该函数,但当您给它少于这个参数时,则不会。去搞清楚。MathWorks 将避免对此给出任何决定性的解释。我怀疑,MATLAB 在应用 subsref 后在内部使用字符串化冒号,因为这就是您在函数中收到文字冒号时看到的内容,并且索引操作似乎自始至终都是这样工作的。例如尝试>> m(3, ':');

我对您的用例的建议本质上是这个答案(也在您的问题的评论中引用),但正如您所建议的,将索引隐藏在名为 paren 的函数中。另外,它使用默认的括号语法而不是调用 subsref,但无论如何都是一样的。使用字符串冒号!

function result = paren(variable, varargin)

    result = variable(varargin{:});
Run Code Online (Sandbox Code Playgroud)

然后调用类似的东西:

>> paren(magic(5), 3, ':');
Run Code Online (Sandbox Code Playgroud)

总之,您不应该指望使用文字 : 作为 MATLAB 中的函数参数,即使它可能适用于特殊情况。使用字符串冒号“:”。

边注

您可以使用 subsref 来调用函数:

>> subsref(@magic, substruct('()', {3}))
Run Code Online (Sandbox Code Playgroud)

通过这种方式,您可以链接函数调用和引用:

>> subsref(subsref(@magic, substruct('()', {3})), substruct('()', {':'}))
Run Code Online (Sandbox Code Playgroud)

但这实际上与使用临时变量是一样的。首先评估内部 subsref,并将其结果作为输入参数传递到外部 subsref 调用中。

即使使用 subsref 的链接机制,您也无法强制 MATLAB 接受两对连续的括号,例如 magic(3)(:)。

>> magic(3)(:)
??? Error: ()-indexing must appear last in an index expression.

>> subs(1) = substruct('()', {3});
>> subs(2) = substruct('()', {':'});
>> subsref(str2func('magic'), subs)
??? Error using ==> subsref
Only a dot field name can follow ()'s.
Run Code Online (Sandbox Code Playgroud)