Main Content

本页的翻译已过时。点击此处可查看最新英文版本。

更新您的代码以接受字符串

在 R2016b 中,MATLAB® 引入了字符串数组作为文本的数据类型。从 R2018b 开始,所有 MathWorks® 产品都兼容字符串数组。兼容意味着如果您可以将文本指定为字符向量或字符向量元胞数组,则还可以将其指定为字符串数组。现在,您可以在自己的代码中采用字符串数组作为文本数据类型。

如果您为其他 MATLAB 用户编写代码,则最好将您的 API 更新为接受字符串数组,同时保持与其他文本数据类型的向后兼容性。采用字符串可使您的代码与 MathWorks 产品保持一致。

如果您的代码中依赖项很少,或者您正在开发新代码,则请考虑使用字符串数组作为您的主要文本数据类型以提高性能。在这种情况下,最佳做法是适当编写或更新您的 API,使之接受字符向量、字符向量元胞数组或字符串数组类型的输入参数。

有关字符串数组和其他术语的定义,请参阅有关字符和字符串数组的术语

什么是字符串数组?

在 MATLAB 中,可以用两种方式存储文本数据。一种方式是使用字符数组,它是一个字符序列,就像数值数组是一个数字序列一样。从 R2016b 开始采用的另一种方式是将一个字符序列存储在一个字符串中。您可以将多个字符串存储在一个字符串数组中。有关详细信息,请参阅字符和字符串

在旧 API 中采用字符串类型的建议方法

如果您的代码有很多依赖项,并且您必须保持向后兼容性,请按照下列方法更新函数和类来实现向后兼容的 API。

函数

  • 接受字符串数组作为输入参数。

    • 如果某个输入参数可以是字符向量或字符向量元胞数组,则更新您的代码,使字符串数组也可以作为输入参数。例如,假设某函数具有一个输入参数,该输入参数可以指定为字符向量(使用单引号)。最佳做法是更新函数,使得该参数可以指定为字符向量或字符串标量(使用双引号)。

  • 在名称-值对组参数中接受字符串作为名称和值。

    • 在名称-值对组参数中,允许将名称指定为字符向量或字符串 - 即将名称用单引号或双引号括起来。如果某个值可以是字符向量或字符向量元胞数组,则更新您的代码,使之也可以是字符串数组。

  • 不要接受字符串数组的元胞数组作为文本输入参数。

    • 字符串数组的元胞数组在每个元胞中都有一个字符串数组。例如,{"hello","world"} 是字符串数组的元胞数组。虽然您可以创建这样的元胞数组,但不推荐将其用于存储文本。字符串数组的元素具有相同的数据类型并以高效方式存储。如果将字符串存储在元胞数组中,则无法利用字符串数组带来的优势。

      但是,如果您的代码接受异构元胞数组作为输入,则考虑接受包含字符串的元胞数组。您可以将这种元胞数组中的任何字符串转换为字符向量。

  • 一般情况下,不要更改输出类型。

    • 如果您的函数返回字符向量或字符向量元胞数组,则即使该函数接受字符串数组作为输入,也不要更改输出类型。例如,fileread 函数接受指定为字符向量或字符串的输入文件名,但该函数以字符向量形式返回文件内容。通过保持输出类型不变,您可以保持向后兼容性。

  • 当函数修改了输入文本时,会返回相同的数据类型。

    • 如果您的函数修改了输入文本并将修改后的文本作为输出参数返回,则输入和输出参数应该具有相同的数据类型。例如,lower 函数接受文本作为输入参数,将其转换为全部小写字母并返回。如果输入参数是字符向量,则 lower 返回字符向量。如果输入是字符串数组,则 lower 返回字符串数组。

  • 考虑向导入函数添加 'TextType' 参数。

    • 如果您的函数从文件导入数据,并且至少有部分数据可以是文本,则考虑添加一个输入参数,该参数指定是将文本作为字符数组还是字符串数组返回。例如,readtable 函数提供 'TextType' 名称-值对组参数。此参数指定 readtable 返回的表是包含字符向量元胞数组形式的文本还是包含字符串数组形式的文本。

  • 将方法视为函数。

    • 要采用字符串,请将方法视作函数。接受字符串数组作为输入参数,并且通常不要更改输出参数的数据类型,如前一节中所述。

  • 不要更改属性的数据类型。

    • 如果某个属性是字符向量或字符向量元胞数组,则不要更改其类型。当您访问此类属性时,返回值仍然是字符向量或者字符向量元胞数组。

      作为替代方案,您可以添加一个作为字符串的新属性,并使其依赖旧属性来保持兼容性。

  • 使用字符串数组设置属性。

    • 如果某个属性可以使用字符向量或字符向量元胞数组来设置,则更新您的类,使之同样可以使用字符串数组来设置。但是,不要更改该属性的数据类型。此时,应将输入字符串数组转换为该属性的数据类型,然后设置属性。

  • 添加 string 方法。

    • 如果您的类已有 char 和/或 cellstr 方法,请添加一个 string 方法。如果类中有对象可以表示为字符向量或字符向量元胞数组,则也要使该对象能够表示为字符串数组。

如何在旧 API 中采用字符串数组

要在旧 API 中采用字符串,您需要接受字符串数组作为输入参数,然后将它们转换为字符向量或字符向量元胞数组。如果您在函数的开头执行此类转换,则无需更新函数的其余部分。

convertStringsToChars 函数提供了一种处理所有输入参数的方法,只转换其中的字符串数组参数。要使您的现有代码接受字符串数组作为输入,请在函数和方法的开头添加对 convertStringsToChars 的调用。

例如,如果您定义了接受三个输入参数的函数 myFunc,则使用 convertStringsToChars 处理所有三个输入。其余的代码保持不变。

function y = myFunc(a,b,c)
    [a,b,c] = convertStringsToChars(a,b,c);
    <line 1 of original code>
    <line 2 of original code>
    ...

在此示例中,参数 [a,b,c] 覆盖了原有的输入参数。如果有任意输入参数不是字符串数组,则该参数保持不变。

如果 myFunc 接受可变数目的输入参数,则处理由 varargin 指定的所有参数。

function y = myFunc(varargin)
    [varargin{:}] = convertStringsToChars(varargin{:});
    ...

性能方面的考虑

在转换一个输入参数时,convertStringsToChars 函数更高效。如果您的函数对性能要求比较高,则您可以一次转换一个输入参数,同时保持代码的其余部分不变。

function y = myFunc(a,b,c)
    a = convertStringsToChars(a);
    b = convertStringsToChars(b);
    c = convertStringsToChars(c);
    ...

在新代码中采用字符串的建议方法

如果您的代码中依赖项很少,或者您正在开发全新代码,请考虑使用字符串数组作为主要文本数据类型。处理大量文本时,字符串数组能够提供良好的性能和高效的内存使用。与字符向量元胞数组不同,字符串数组具有同构数据类型。字符串数组更有利于轻松编写可维护的代码。要在使用字符串数组的同时保持与其他文本数据类型的向后兼容性,请遵循这些方法。

函数

  • 接受任何文本数据类型作为输入参数。

    • 如果某个输入参数可以是字符串数组,则也允许它是字符向量或字符向量元胞数组。

  • 接受字符数组作为名称-值对组参数中的名称和值。

    • 在名称-值对组参数中,允许将名称指定为字符向量或字符串 - 即将名称用单引号或双引号括起来。如果某个值可以是字符串数组,则使之也可以是字符向量或字符向量元胞数组。

  • 不要接受字符串数组的元胞数组作为文本输入参数。

    • 字符串数组的元胞数组在每个元胞中都有一个字符串数组。虽然您可以创建这样的元胞数组,但不推荐将其用于存储文本。如果您的代码使用字符串作为主要文本数据类型,则将文本的多个片段存储在一个字符串数组中,而不是存储在字符串数组的元胞数组中。

      但是,如果您的代码接受异构元胞数组作为输入,则考虑接受包含字符串的元胞数组。

  • 一般情况下,返回字符串。

    • 如果您的函数返回文本形式的输出参数,则将它们作为字符串数组返回。

  • 当函数修改了输入文本时,会返回相同的数据类型。

    • 如果您的函数修改了输入文本并将修改后的文本作为输出参数返回,则输入和输出参数应该具有相同的数据类型。

  • 将方法视为函数。

    • 如前一节所述,接受字符向量和字符向量元胞数组作为输入参数。一般情况下,将字符串作为输出返回。

  • 将属性指定为字符串数组。

    • 如果某个属性包含文本,则使用字符串数组设置该属性。当您访问该属性时,将它的值作为字符串数组返回。

如何在新代码中保持兼容性

当您编写新代码或修改代码以使用字符串数组作为主要文本数据类型时,请保持与其他文本数据类型的向后兼容性。您可以接受字符向量或字符向量元胞数组作为输入参数,然后立即将它们转换为字符串数组。如果您在函数的开头执行此转换,则您的其余代码只能使用字符串数组。

convertCharsToStrings 函数提供一种处理所有输入参数的方法,只转换其中的字符向量参数或字符向量元胞数组参数。要使您的新代码接受这些文本数据类型作为输入,请在函数和方法的开头添加对 convertCharsToStrings 的调用。

例如,如果您定义了接受三个输入参数的函数 myFunc,则使用 convertCharsToStrings 处理所有三个输入。

function y = myFunc(a,b,c)
    [a,b,c] = convertCharsToStrings(a,b,c);
    <line 1 of original code>
    <line 2 of original code>
    ...

在此示例中,参数 [a,b,c] 覆盖了原有的输入参数。如果有任意输入参数不是字符向量或字符向量元胞数组,则该参数保持不变。

如果 myFunc 接受可变数目的输入参数,则处理由 varargin 指定的所有参数。

function y = myFunc(varargin)
    [varargin{:}] = convertCharsToStrings(varargin{:});
    ...

性能方面的考虑

在转换一个输入参数时,convertCharsToStrings 函数更高效。如果您的函数对性能要求比较高,则您可以一次转换一个输入参数,同时保持代码的其余部分不变。

function y = myFunc(a,b,c)
    a = convertCharsToStrings(a);
    b = convertCharsToStrings(b);
    c = convertCharsToStrings(c);
    ...

如何手动转换输入参数

尽可能避免手动转换包含文本的输入参数,而改为使用 convertStringsToCharsconvertCharsToStrings 函数。自行检查输入参数的数据类型并进行转换不仅繁琐,而且容易出错。

如果您必须转换输入参数,请使用下表中的函数。

转换

函数

将字符串标量转换为字符向量

char

将字符串数组转换为字符向量元胞数组

cellstr

将字符向量转换为字符串标量

string

将字符向量元胞数组转换为字符串数组

string

如何检查参数数据类型

要检查可能包含文本的输入参数的数据类型,请考虑使用下表中显示的模式。

要求的输入参数类型

旧检查

新检查

字符向量或字符串标量

ischar(X)

ischar(X) || isStringScalar(X)

validateattributes(X,{'char','string'},{'scalartext'})

字符向量或字符串标量

validateattributes(X,{'char'},{'row'})

validateattributes(X,{'char','string'},{'scalartext'})

非空字符向量或字符串标量

ischar(X) && ~isempty(X)

(ischar(X) || isStringScalar(X)) && strlength(X) ~= 0

(ischar(X) || isStringScalar(X)) && X ~= ""

字符向量元胞数组或字符串数组

iscellstr(X)

iscellstr(X) || isstring(X)

任何文本数据类型

ischar(X) || iscellstr(X)

ischar(X) || iscellstr(X) || isstring(X)

检查空字符串

空字符串是指没有字符的字符串。MATLAB 将空字符串显示为一对中间没有任何内容的双引号 ("")。但是,一个空字符串仍然是一个 1×1 字符串数组。它不是空数组。

推荐使用 strlength 函数检查字符串是否为空。

str = "";
tf = (strlength(str) ~= 0)

注意

不要使用 isempty 函数检查空字符串。一个空字符串没有字符,但仍然是一个 1×1 字符串数组。

strlength 函数返回字符串数组中每个字符串的长度。如果字符串必须是字符串标量,且不为空,则两个条件都检查。

tf = (isStringScalar(str) && strlength(str) ~= 0)

如果 str 既可以是字符向量也可以是字符串标量,则您仍可使用 strlength 来确定它的长度。如果输入参数是空字符向量 (''),则 strlength 返回 0

tf = ((ischar(str) || isStringScalar(str)) && strlength(str) ~= 0)

检查空字符串数组

实际上,空字符串数组是空数组,即至少有一个维度的长度为 0 的数组。

要创建空字符串数组,推荐的方法是使用 strings 函数,并指定至少一个输入参数为 0。当输入为空字符串数组时,isempty 函数返回 1

str = strings(0);
tf = isempty(str)

strlength 函数返回与输入字符串数组大小相同的数值数组。如果输入是一个空字符串数组,则 strlength 返回一个空数组。

str = strings(0);
L = strlength(str)

检查缺失字符串

字符串数组还可以包含缺失字符串。缺失字符串相当于数值数组的 NaN。它指示字符串数组包含缺失值的位置。缺失字符串显示为 <missing>(不带引号)。

您可以使用 missing 函数创建缺失字符串。要检查缺失字符串,推荐的方法是使用 ismissing 函数。

str = string(missing);
tf = ismissing(str)

注意

不要通过将字符串与缺失字符串进行比较来检查缺失字符串。

缺失字符串不等于自身,就像 NaN 不等于它自身一样。

str = string(missing);
f = (str == missing)

有关字符和字符串数组的术语

MathWorks 文档使用下列术语来描述字符和字符串数组。为保持一致,请在您自己的文档、错误消息和警告中使用这些术语。

  • 字符向量 - 由字符构成的 1×n 数组,数据类型为 char

  • 字符数组 - 由字符构成的 m×n 数组,数据类型为 char

  • 字符向量元胞数组 - 每个元胞包含一个字符向量的元胞数组。

  • 字符串字符串标量 - 1×1 字符串数组。一个字符串标量可以包含 1×n 字符序列,但它本身是一个对象。区分“字符串标量”和“字符向量”是为了精确表示大小和数据类型。否则,您可以在说明中只使用“字符串”。

  • 字符串向量 - 1×nn×1 字符串数组。如果只允许使用一种大小,请在文档中加以说明。例如,使用“1×n 字符串数组”来描述该大小的数组。

  • 字符串数组 - m×n 字符串数组。

  • 空字符串 - 没有字符的字符串标量。

  • 空字符串数组 - 至少有一个维度的大小为 0 的字符串数组。

  • 缺失字符串 - 作为缺失值的字符串标量(显示为 <missing>)。

另请参阅

| | | | | | | | | | | |

相关主题