主要内容

使用代码分析器检查代码中的错误和警告

R2026b

MATLAB® 代码分析器可自动检查您的代码有无编码问题。您可以查看有关您代码的警告和错误消息,并基于这些消息修改您的文件。这些消息会自动持续更新,因此您可以看到您的更改是否解决了消息中指明的问题。某些消息提供其他信息和/或自动代码更正。

此处 Code Analyzer Checks 提供了 MATLAB 代码分析器执行的所有检查的列表。

启用持续代码检查

要启用持续代码检查,请在主页选项卡上的环境部分中,点击 设置。选择 MATLAB > 代码分析器,然后选中启用持续代码检查复选框。将下划线选项设置为对警告、错误和信息性消息添加下划线。

启用持续代码检查后,MATLAB 会在编辑器中显示有关代码的警告和错误消息。例如,示例文件 lengthofline.m 包含几个错误和警告。将代码复制到编辑器中,并将文件另存为 lengthofline.m。

function [len,dims] = lengthofline(hline)
%LENGTHOFLINE Calculates the length of a line object
%   LEN = LENGTHOFLINE(HLINE) takes the handle to a line object as the
%   input, and returns its length.  The accuracy of the result is directly
%   dependent on the number of distinct points used to describe the line.
%
%   [LEN,DIM] = LENGTHOFLINE(HLINE) additionally tells whether the line is
%   2D or 3D by returning either a numeric 2 or 3 in DIM.  A line in a
%   plane parallel to a coordinate plane is considered 2D.
%
%   If HLINE is a matrix of line handles, LEN and DIM will be matrices of results.
%
%   Example:
%       figure; h2 = plot3(1:10,rand(1,10),rand(10,5));
%       hold on; h1 = plot(1:10,rand(10,5));
%       [len,dim] = lengthofline([h1 h2])

%   Copyright 1984-2004 The MathWorks, Inc. 

% Find input indices that are not line objects
nothandle = ~ishandle(hline);
for nh = 1:prod(size(hline))
    notline(nh) = ~ishandle(hline(nh)) || ~strcmp('line',lower(get(hline(nh),'type')));
end

len = zeros(size(hline));
for nl = 1:prod(size(hline))
    % If it's a line, get the data and compute the length
    if ~notline(nl)
        flds = get(hline(nl));
        fdata = {'XData','YData','ZData'};
        for nd = 1:length(fdata)
            data{nd} = getfield(flds,fdata{nd});
        end
        % If there's no 3rd dimension, or all the data in one dimension is
        % unique, then consider it to be a 2D line.
        if isempty(data{3}) | ...
               (length(unique(data{1}(:)))==1 | ...
                length(unique(data{2}(:)))==1 | ...
                length(unique(data{3}(:)))==1)
            data{3} = zeros(size(data{1}));
            dim(nl) = 2;
        else
            dim(nl) = 3;
        end
        % Do the actual computation
        temp = diff([data{1}(:) data{2}(:) data{3}(;)]);
        len(nl) = sum([sqrt(dot(temp',temp'))])
    end
end

% If some indices are not lines, fill the results with NaNs.
if any(notline(:))
    warning('lengthofline:FillWithNaNs', ...
        '\n%s of non-line objects are being filled with %s.', ...
        'Lengths','NaNs','Dimensions','NaNs')
    len(notline) = NaN;
    dim(notline) = NaN;
end
    
if nargout > 1
    dims = dim;
end

查看文件的代码分析器状态

当您在编辑器中打开文件时,指示标记条顶部的消息指示标记会显示该文件的整体代码分析器状态。

消息指示标记描述

文件包含语法错误或其他重大问题。

文件包含警告,但没有错误。

文件包含信息性消息,但没有警告或错误。

文件不包含错误、警告或信息性消息。

持续代码检查被禁用。

例如,在 lengthofline.m 中,消息指示标记是 ,这意味着文件包含至少一个错误。

lengthofline file in the Editor with the red error symbol displayed in the indicator bar

查看代码分析器消息

要转到包含消息的第一个代码片段,请点击消息指示标记。标识的代码片段以红色(表示错误)、橙色(表示警告)或蓝色(信息性消息)下划线标出。如果文件包含错误,点击消息指示标记会转至第一个错误。

例如,在 lengthofline.m 中,当您点击消息指示标记时,光标移至第 47 行,第一个错误发生在该行。MATLAB 在指示标记条中的错误标记旁边显示该行的错误。多条消息可能代表存在一个问题或多个问题。解决一条消息可能会同时解决所有消息。或者,在解决一条消息后其他消息可能有变化,或者您需要采取的操作可能变得更清晰。

lengthofline file in the Editor after clicking the message indicator. Three errors display next to the error marker in the indicator bar.

要转到包含消息的下一代码片段,请点击消息指示标记。您也可以点击指示标记条中的某个标记,以转至该标记所代表的行。例如,点击 lengthofline.m 中指示标记条中的第一个标记。光标移至第 21 行的开头。

要查看代码片段的消息,请在带下划线的代码片段内移动鼠标指针。您也可以将光标放在带下划线的代码片段中,然后按 Ctrl+M。如果该消息还有附加信息,则会包括一个详细信息按钮。点击该按钮可显示附加信息和任何建议的用户操作。

lengthofline file in the Editor showing a warning message with a details button

修复代码中的问题

对于代码文件中的每条消息,请修改代码以解决消息中指明的问题。当您修改代码时,消息指示标记和下划线会更新以反映您所做的更改,即使您没有保存文件也是如此。

例如,在 lengthofline.m 的第 47 行,该消息提示存在分隔符不平衡问题。当您在每个分隔符上移动箭头键时,MATLAB 并未指示存在不匹配。但是,代码分析检测到 data{3}(;) 中有分号,并将其解释为语句结束符。

lengthofline file in the Editor after clicking the message indicator. Three errors display next to the error marker in the indicator bar.

要解决此问题,请在第 47 行中将 data{3}(;) 更改为 data{3}(:)。只需一次更改就解决了第 47 行的所有消息,该行不再显示下划线。因为通过更改移除了文件中的唯一错误,所以栏顶部的消息指示标记从 变为 ,指示只存在警告和信息性消息。

对于某些消息,MATLAB 建议您应用自动修复来解决问题。如果某个问题有可用的自动修复,代码片段会突出显示,并且消息中包含修复按钮。

lengthofline file in the Editor showing a warning message with a fix button

例如,在 lengthofline.m 中的第 22 行,将鼠标放在带下划线并突出显示的代码片段 prod 上。显示的消息包括修复按钮。

如果您知道如何解决问题(也许是根据以往的经验),则可以点击修复按钮或按 Alt+Enter。如果您不熟悉该问题,可以右键点击突出显示的代码。上下文菜单中的第一个项目显示了建议的修复。选择要应用修复的项目。

lengthofline file in the Editor showing the context menu. The first item in the menu is the suggested fix.

如果某个问题存在多个实例,则 MATLAB 可能会提议为该问题的所有实例应用建议的修复。要对问题的所有实例应用修复,可以右键点击突出显示的代码,然后选择修复此问题的所有(n个)实例。此选项并非对所有建议的修复都可用。

在修改代码以解决所有消息中的问题或禁用指定的消息后,消息指示标记变为绿色。请参阅示例文件 lengthofline2.m,其中所有消息中的问题都已得到解决。

function [len,dims] = lengthofline2(hline)
%LENGTHOFLINE Calculates the length of a line object
%   LEN = LENGTHOFLINE(HLINE) takes the handle to a line object as the
%   input, and returns its length.  The accuracy of the result is directly
%   dependent on the number of distinct points used to describe the line.
%
%   [LEN,DIM] = LENGTHOFLINE(HLINE) additionally tells whether the line is
%   2D or 3D by returning either a numeric 2 or 3 in DIM.  A line in a
%   plane parallel to a coordinate plane is considered 2D.
%
%   If HLINE is a matrix of line handles, LEN and DIM will be matrices of results.
%
%   Example:
%       figure; h2 = plot3(1:10,rand(1,10),rand(10,5));
%       hold on; h1 = plot(1:10,rand(10,5));
%       [len,dim] = lengthofline([h1 h2])

%   Copyright 1984-2005 The MathWorks, Inc. 

% Find input indices that are not line objects
nothandle = ~ishandle(hline);
notline = false(size(hline));
for nh = 1:numel(hline)
    notline(nh) = nothandle(nh) || ~strcmpi('line',get(hline(nh),'type'));
end

len = zeros(size(hline));
dim = len;
for nl = 1:numel(hline)
    % If it's a line, get the data and compute the length
    if ~notline(nl)
        flds = get(hline(nl));
        fdata = {'XData','YData','ZData'};
        data = cell(size(fdata));
        for nd = 1:length(fdata)
            data{nd} = flds.(fdata{nd});
        end
        % If there's no 3rd dimension, or all the data in one dimension is
        % unique, then consider it to be a 2D line.
        if isempty(data{3}) || ...
               (length(unique(data{1}(:)))==1 || ...
                length(unique(data{2}(:)))==1 || ...
                length(unique(data{3}(:)))==1)
            data{3} = zeros(size(data{1}));
            dim(nl) = 2;
        else
            dim(nl) = 3;
        end
        % Do the actual computation
        temp = diff([data{1}(:) data{2}(:) data{3}(:)]);
        len(nl) = sum(sqrt(dot(temp',temp'))) %#ok<NOPRT>
    end
end

% If some indices are not lines, fill the results with NaNs.
if any(notline(:))
    warning('lengthofline2:FillWithNaNs', ...
        '\n%s of non-line objects are being filled with %s.', ...
        'Lengths','NaNs','Dimensions','NaNs')
    len(notline) = NaN;
    dim(notline) = NaN;
end
    
if nargout > 1
    dims = dim;
end

使用“代码问题”面板分析文件

自 R2025a 起

您可以使用代码问题面板查看有关代码的错误和警告消息。代码问题面板会显示 MATLAB 代码分析器在自动检查您的代码时发现的编码问题。

要打开代码问题面板,请转至编辑器或实时编辑器选项卡,然后在分析部分中,点击 代码问题。或者,点击指示标记条顶部的消息指示标记。默认情况下,代码问题面板在桌面右侧打开。要隐藏代码问题面板,请点击边栏中的代码问题 图标。

Code Issues panel showing 3 errors, 2 warnings, and 11 info messages found in the lengthofline.m file

您可以使用代码问题面板顶部的选项来更改该面板中显示的消息:

  • 更改在哪些文件中查找问题 - 在“代码问题”面板左上角的下拉列表中,选择当前文件以显示当前文件的错误、警告和消息性消息,或选择打开文件以显示所有打开文件的错误、警告和信息性消息。

  • 按类型过滤消息 - 在“代码问题”面板的右上角,点击“错误””、“警告” 或“信息” 按钮,以切换是否显示该类型的消息。例如,要仅显示错误,请点击错误按钮 将其打开,并点击警告按钮 和信息按钮 将其关闭。

  • 按文本过滤消息 - 使用下拉列表下方的搜索字段按文本过滤消息列表。例如,要仅显示包含单词 Variable 的消息,请在搜索字段中输入单词 Variable。

使用代码分析器分析文件

自 R2022b 起

您可以使用 Code Analyzer 为一个文件夹中的所有文件创建代码分析器消息报告。

要打开 App,请执行以下操作:

  • MATLAB 工具条:在 App 选项卡上的 MATLAB 下,点击该 App 图标:Code Analyzer App Icon。

  • MATLAB 命令提示符:输入 codeAnalyzer。

Code Analyzer app showing an overall summary of code issues and code health details

使用 codeIssues 对象标识和存储文件中的问题

自 R2022b 起

您可以使用 codeIssues 以编程方式在代码中查找和存储问题。codeIssues 对象可存储由 MATLAB 代码分析器找到的问题。您可以对在一个或多个指定文件或文件夹中找到的问题进行排序和过滤,这些操作可在命令行上以编程方式执行,也可在代码分析器中以交互方式执行。

例如,您可以生成一个 codeIssues 对象,其中包含指定文件中的问题:

issues = codeIssues("test.m")
issues = 

  codeIssues with properties:

                         Date: 18-Oct-2022 14:18:54
                      Release: "R2023a"
                        Files: "C:\MyCode\test.m"
    CodeAnalyzerConfiguration: "active"
                       Issues: [3×10 table]
             SuppressedIssues: [0×11 table]


    Issues table preview

    Location    Severity    Fixability                                            Description                                             CheckID    LineStart    LineEnd    ColumnStart    ColumnEnd       FullFilename   
    ________    ________    __________    ____________________________________________________________________________________________    _______    _________    _______    ___________    _________    __________________

    "test.m"      info        manual      "Variable appears to change size on every loop iteration. Consider preallocating for speed."    AGROW          3           3            1             3        "C:\MyCode\test.m"
    "test.m"      info        auto        "Add a semicolon after the statement to hide the output (in a script)."                         NOPTS          6           6            3             3        "C:\MyCode\test.m"
    "test.m"      info        auto        "string('...') is not recommended. Use "..." instead."                                          STRQUOT        8           8            1            13        "C:\MyCode\test.m"

在 R2023b 中: 包含在一个 codeIssues 对象中的信息可以使用 export 导出。

调整代码分析器消息指示标记和消息

您可以指定为哪种类型的编码问题加上下划线,以契合您当前开发阶段的需求。例如,首次编码时,您可能希望只对错误使用下划线,这是因为警告会带来纷扰。要更改下划线设置,请在主页选项卡的环境部分中,点击 设置。选择 MATLAB > 代码分析器,然后选择下划线选项。

您还可以调整在分析代码时看到的消息。代码分析并不能提供关于每种情况的完美信息。有时,您可能不想根据消息更改代码。如果您不想更改代码,并且不希望看到特定行的标记和消息,可隐藏它们。例如,示例文件 lengthofline.m 的第 48 行的第一条消息是用分号终止语句以隐藏输出(在函数中)。在语句末尾添加分号隐藏输出,这是一种常见做法。针对生成输出但缺少终止分号的行,代码分析可向您发出警报。如果您想查看第 48 行后的输出,请不要按消息指示添加分号。

您可以通过以下方式隐藏(关闭)警告和错误消息的指示标记:

  • 在当前文件中隐藏消息实例。

  • 在当前文件中隐藏所有消息实例。

  • 在所有文件中隐藏所有消息实例。

您不能隐藏诸如语法错误之类的错误消息。

在当前文件中隐藏消息实例

您可以在当前文件中隐藏代码分析器消息的特定实例。例如,要隐藏示例文件 lengthofline.m 中第 48 行的消息,请右键点击第 48 行的第一条下划线,然后选择隐藏‘使用分号终止语句...’ > 在此行中。

注释 %#ok<NOPRT> 出现在行尾,指示 MATLAB 对该行隐藏用分号终止语句以隐藏输出(在函数中)代码分析器消息。该消息的下划线和指示标记条中对应的标记随即消失。

如果一行中包含两条您不想显示的消息,请分别右键点击每条下划线,然后从上下文菜单中选择适当的条目。%#ok 语法将扩展。例如,隐藏示例文件 lengthofline.m 中第 48 行的两条消息会在行尾添加注释 %#ok<NBRAK,NOPRT>。

即使代码分析器设置为启用此消息,隐藏的消息的特定实例也不会显示,这是因为 %#ok 的优先级高于设置。如果您以后决定要为该行显示用分号终止语句以隐藏输出(在函数中)代码分析器消息,请从该行中删除 %#ok<NOPRT>。

在当前文件中隐藏所有消息实例

您可以在当前文件中隐藏特定代码分析器消息的所有实例。例如,要隐藏示例文件 lengthofline.m 中第 48 行的消息的所有实例,请右键点击第 48 行的第一条下划线,然后选择取消‘使用分号终止语句...’ > 在此文件中。

注释 %#ok<*NOPRT> 出现在行尾,指示 MATLAB 隐藏当前文件中用分号终止语句以隐藏输出(在函数中)代码分析器消息的所有实例。此消息的所有下划线以及消息指示标记条中对应的标记都将消失。

如果一行中包含两条您不想在当前文件中显示的消息,请分别右键点击每条下划线,然后从上下文菜单中选择适当的条目。%#ok 语法将扩展。例如,隐藏示例文件 lengthofline.m 中第 48 行的两条消息会添加注释 %#ok<*NBRAK,*NOPRT>。

即使代码分析器设置为启用此消息,此消息也不会显示,这是因为 %#ok 的优先级高于设置。如果您以后决定要在当前文件中显示用分号终止语句以隐藏输出(在函数中)代码分析器消息的所有实例,请从该行中删除 %#ok<*NOPRT>。

在所有文件中隐藏所有消息实例

您可以在所有文件中禁用代码分析器消息的所有实例。例如,要隐藏示例文件 lengthofline.m 中第 48 行的消息在所有文件中的所有实例,请右键点击第 48 行的第一条下划线,然后选择隐藏‘使用分号终止语句...’ > 在所有文件中。此选项会修改代码分析器设置。

如果您知道要隐藏哪些条消息,可以直接使用代码分析器设置禁用它们:

  1. 在主页选项卡的环境部分,点击 设置。

  2. 选择 MATLAB > 代码分析器。

  3. 搜索消息以查找要隐藏的消息。

  4. 清除与您要在所有文件中隐藏的每条消息关联的复选框。

  5. 点击确定。

保存并重新使用代码分析器消息设置

您可以设置选项来启用或禁用特定代码分析器消息,然后将这些设置保存到文件中。当您希望将设置文件用于某特定文件时,可从代码分析器设置中选择它。这些设置文件会一直有效,直到您选择另一设置文件为止。通常,当您希望将某特定设置文件用于一部分文件时,要更改设置文件。

要将设置保存到文件中,请执行下列步骤:

  1. 在主页选项卡的环境部分,点击 设置。

  2. 选择 MATLAB > 代码分析器。

  3. 启用或禁用特定消息或消息类别。

  4. 点击“操作”按钮 ,选择另存为,然后将设置保存为 txt 文件。

  5. 点击确定。

您可以对任何 MATLAB 文件重复使用这些设置,或向另一用户提供该设置文件。要使用保存的设置,请执行以下操作:

  1. 在主页选项卡的环境部分,点击 设置。

  2. 选择 MATLAB > 代码分析器。

  3. 打开当前设置列表,选择浏览。

  4. 从任何设置文件中进行选择。

    您选择的设置对于所有 MATLAB 文件都保持有效,直到您选择另一组代码分析器设置为止。

启用自定义检查项并配置现有检查项

自 R2023a 起

您可以通过代码分析器配置 MATLAB 编辑器中显示的现有检查项,并通过将名为 codeAnalyzerConfiguration.json 的文件放在一个资源文件夹中来添加自定义检查项。配置文件在包含该资源文件夹及其所有子文件夹的文件夹中有效。

您可以修改现有代码分析器检查项,包括检查项是否已启用及其严重性、消息文本和其他可能有的检查项参数(例如限制函数的输入和输出参量数目的参数)。您还可以创建在使用特定函数时触发的自定义检查项。有关配置代码分析器检查项的详细信息,请参阅Customize Code Analyzer Checks Using Configuration File。

使用函数 matlab.codeanalysis.validateConfiguration 验证您的 codeAnalyzerConfiguration.json 配置文件的格式是否正确。

了解包含隐藏消息的代码

如果您收到包含隐藏消息的代码,您可能需要查看消息,而不必首先取消隐藏它们。由于以下任何原因,消息可能处于隐藏状态:

  • 一个或多个 %#ok<message-ID> 指令所在的代码行引发了 <message-ID> 指定的消息。

  • 一个或多个 %#ok<*message-ID> 指令所在的文件引发了 <message-ID> 指定的消息。

  • 消息在代码分析器设置窗格中清除。

  • 默认情况下,消息被禁用。

要确定隐藏消息的原因,请以文件作为输入调用 codeIssues。

issues = codeIssues("myFile.m")

输出 issues 将具有属性 SuppressedIssues,包含列出文件中所有隐藏问题的表。请查看与每个问题相关联的消息,以了解为何隐藏该消息。

了解代码分析的局限

代码分析是一个非常有用的工具,但有一些局限:

  • 代码分析有时无法生成您预期的代码分析器消息。

    按照设计,代码分析会尝试最大限度地减少其返回的不正确的消息数,即使此行为导致某些问题不被发现也如此。

  • 代码分析有时生成的消息不适用于您的情形。

    点击详细信息按钮可显示消息的附加信息,以帮助您确定该消息是否适用于您的情形。错误消息几乎总说明存在问题。但是,许多警告是一些建议,指示您查看代码中的某些异常的内容,但在您特定的情况下可能正确。

    如果您确信某警告消息不适用于您的情形,可隐藏该消息。如果您隐藏消息的理由不明显或模糊,请包含注释加以说明。这样,阅读您的代码的用户就可以知道这种情况。

    有关详细信息,请参阅调整代码分析器消息指示标记和消息。

区分函数名称与变量名称

代码分析无法始终将函数名称与变量名称区分开。对于以下代码,如果启用了代码分析器消息,则代码分析会返回消息 Code Analyzer cannot determine whether xyz is a variable or a function, and assumes it is a function。代码分析无法做出判断,这是因为 xyz 未向其分配明显的值。但是,代码可能已将该值放入工作区中,只是代码分析无法检测到。

function y=foo(x)
   .
   .
   .
   y = xyz(x);
end

例如,在以下代码中,xyz 可以为函数,或者是从 MAT 文件加载的变量。代码分析无法做出判断。

function y=foo(x)
    load abc.mat
    y = xyz(x);
end
当您使用 eval、evalc、evalin 或 assignin 函数时,变量也有可能不被代码分析检测到。

如果代码分析将变量误认为是函数,请执行以下操作之一:

  • 初始化该变量,以便代码分析不将其视为函数。

  • 对于 load 函数,请在 load 命令行中显式指定变量名称。例如:

     function y=foo(x)
         load abc.mat xyz
         y = xyz(x);
     end

区分结构体与句柄对象

代码分析无法始终将结构体与句柄对象区分开。在以下代码中,如果 x 是一个结构体,您可能收到代码分析器消息,指示代码从未使用该结构体的更新值。但如果 x 是一个句柄对象,则该代码可能正确。

function foo(x)
		x.a = 3;
end

代码分析无法确定 x 是结构体还是句柄对象。为了最大限度减少不正确的消息数,代码分析对以上代码不返回任何消息,即使它可能包含细微和严重的问题也如此。

区分内置函数与重载函数

如果在类中或在路径上重载某些内置函数,则代码分析器消息可能适用于该内置函数,但不适用于您所调用的重载函数。本例中,在消息显示的行上隐藏该消息或者在整个文件隐藏它。

有关隐藏消息的信息,请参阅调整代码分析器消息指示标记和消息。

确定变量的大小或形状

代码分析在确定变量的类型和矩阵的形状时的能力有限。代码分析生成的消息可能适合多数常见情况(例如向量)。但是,这些消息可能不适用于不太常见的情况(例如矩阵)。

分析具有超类的类定义

代码分析器仅提供有限的功能检查具有超类的类定义。例如,代码分析器不总能确定类是否为句柄类,但它有时能验证类中使用的自定义属性(如果这些属性是从某个超类继承的)。在分析类定义时,代码分析器会尽量使用来自超类的信息,但它往往无法获得足够的信息做出肯定的决定。

分析类方法

多数类方法都必须至少包含一个参量,该参量是与方法属于相同类的对象。但此参量并不一定总是第一个参量。当它是第一个参量时,代码分析可确定参量是否属于您所定义类的对象,并且是否可执行各种检查。例如,代码分析可以检查属性和方法名称是否存在并且拼写是否正确。但是,当代码分析无法确定对象是否属于您所定义类的参量时,它无法提供这些检查。

启用 MATLAB 编译器部署消息

通过更改此消息类别的代码分析器设置,可以在处理文件时选择显示或隐藏 MATLAB 编译器部署消息。您的选择可能取决于您是否在处理要部署的文件。更改此设置会同时在编辑器中更改该设置。同样,在编辑器中更改该设置也会更改此设置。但是,如果在编辑器中修改设置时代码分析器设置是打开的,则更改不会反映在“设置”窗口中。无论您在编辑器还是“设置”窗口中更改设置,更改都会应用于编辑器和代码分析器报告。

要启用 MATLAB Compiler™ 部署消息,请执行以下操作:

  1. 在主页选项卡的环境部分,点击 设置。

  2. 选择 MATLAB > 代码分析器。

  3. 点击搜索字段旁边的向下箭头,然后选择显示类别中的消息 > MATLAB Compiler (部署)信息。

  4. 点击 MATLAB Compiler (部署)消息类别标题右侧的启用类别按钮。

  5. 清除不想为您的代码显示的消息。

  6. 决定您是否要保存这些设置,以便下次您处理要部署的文件时可重复使用它们。

您可按保存并重新使用代码分析器消息设置中所述创建的设置 txt 文件包括该设置的状态。

另请参阅

| |

主题

教学资源