Обновите код, чтобы принимать строки

В R2016b, MATLAB® введен строковые массивы как тип данных для текста. Как и R2018b, все MathWorks® продукты совместимы со строковыми массивами. Совместимый означает, что если вы можете задать текст как вектор символов или массив ячеек векторов символов, то вы также можете задать его как строковые массивы. Теперь можно принять строковые массивы как тип текстовых данных в собственном коде.

Если вы записываете код для других пользователей MATLAB, то вам выгодно обновить свой API, чтобы принимать строковые массивы, сохраняя при этом обратную совместимость с другими типами текстовых данных. Принятие строк делает ваш код совместимым с продуктами MathWorks.

Если ваш код имеет несколько зависимостей, или если вы разрабатываете новый код, рассмотрите использование строковых массивов в качестве основного типа текстовых данных для повышения эффективности. В этом случае лучшая практика состоит в том, чтобы записать или обновить свой API, чтобы принять входные параметры, которые векторы символов, массивы ячеек векторов символов или строковых массивов.

Определения строковых массивов и других терминов см. в Терминологии для символов и Строковых массивов.

Что такие Строковые массивы?

В MATLAB можно хранить текстовые данные двумя способами. Один из способов - использовать символьный массив, который является последовательностью символов, так же как числовой массив является последовательностью чисел. Или, начиная с R2016b, другой способ - хранить последовательность символов в строке. Можно хранить несколько строк в строковых массивах. Для получения дополнительной информации смотрите Символы и строки.

Рекомендуемые подходы для принятия строк в старых API

Когда ваш код имеет много зависимостей, и вы должны поддерживать обратную совместимость, следуйте этим подходам для обновления функций и классов, чтобы представить совместимый API.

Функции

  • Примите строковые массивы как входные параметры.

    • Если входной параметр может быть либо вектор символов, либо массив ячеек векторов символов, обновите код так, чтобы аргумент также мог быть строковыми массивами. Для примера рассмотрим функцию, которая имеет входной параметр, которую можно задать в качестве вектора символов (используя одинарные кавычки). Лучшая практика состоит в том, чтобы обновить функцию, чтобы аргумент мог быть задан как вектор символов или как строковый скаляр (с помощью двойных кавычек).

  • Примите строки как имена, так и значения в аргументах пары "имя-значение".

    • В аргументах пары "имя-значение" разрешите, чтобы имена задавались как векторы символов, так и как строки - то есть с одинарными или двойными кавычками вокруг имени. Если значение может быть вектором символов или массивом ячеек векторов символов, то обновите код так, чтобы он также мог быть строковыми массивами.

  • Не принимайте массивы ячеек строковых массивов для текстовых входных параметров.

    • Массив ячеек из строковых массивов имеет строковый массив в каждой камере. Для примера, {"hello","world"} - массив ячеек из строковых массивов. Пока можно создать такой массив ячеек, он не рекомендуется для хранения текста. Элементы массива строковых массивов имеют совпадающий тип данных и хранятся эффективно. Если вы храните строки в массиве ячеек, то теряете преимущества использования строковых массивов.

      Однако, если ваш код принимает гетерогенные массивы ячеек как входы, рассмотрите принятие массивов ячеек, которые содержат строки. Можно преобразовать любые строки в таком массиве ячеек в векторы символов.

  • В целом не изменяйте тип выхода.

    • Если ваша функция возвращает вектор символов или массив ячеек векторов символов, то не изменяйте тип выхода, даже если функция принимает строковые массивы как входы. Для примера, fileread функция принимает вход имя файла, заданное как вектор символов или строка, но функция возвращает содержимое файла как вектор символов. Сохраняя тип выхода тем же самым, можно сохранить обратную совместимость.

  • Возвращает тот совпадающий тип данных, когда функция изменяет входной текст.

    • Если ваша функция изменяет входной текст и возвращает измененный текст в качестве выходного аргумента, то входной и выходной аргументы должны иметь совпадающий тип данных. Для примера, lower функция принимает текст как входной параметр, преобразует его во все строчные буквы и возвращает его. Если входной параметр является вектором символов, то lower возвращает вектор символов. Если вход является строковыми массивами, то lower возвращает строковые массивы.

  • Рассмотрите добавление 'TextType' аргумент в функции импорта.

    • Если ваша функция импортирует данные из файлов, и, по крайней мере, некоторые из этих данных могут быть текстами, то рассмотрите добавление входного параметра, которое задает, возвращать ли текст как символьный массив или строковые массивы. Для примера, readtable функция обеспечивает 'TextType' аргумент пары "имя-значение". Этот аргумент задает, readtable возвращает таблицу с текстом в массивах ячеек из векторов символов или строковых массивов.

Классы

  • Относитесь к методам как к функциям.

    • Для принятия строк, обрабатывайте методы, как будто они являются функциями. Примите строковые массивы как входные параметры и в целом не изменяйте тип данных выходных аргументов, как описано в предыдущем разделе.

  • Не изменяйте типы данных свойств.

    • Если свойство является вектором символов или массивом ячеек из векторов символов, то не изменяйте его тип. Когда вы получаете доступ к такому свойству, возвращаемое значение все еще остается вектором символов или массивом ячеек из векторов символов.

      В качестве альтернативы можно добавить новое свойство, являющееся строкой, и сделать его зависимым от старого свойства для поддержания совместимости.

  • Задайте свойства с помощью строковых массивов.

    • Если можно задать свойство с помощью вектора символов или массива ячеек векторов символов, обновите класс, чтобы задать это свойство также с помощью строковых массивов. Однако не изменяйте тип данных свойства. Вместо этого преобразуйте вход строковых массивов в тип данных свойства, а затем задайте свойство.

  • Добавить a 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);
    ...

Как вручную преобразовать входные параметры

Если это вообще возможно, избегайте ручного преобразования входных параметров, которые содержат текст, и вместо этого используйте convertStringsToChars или convertCharsToStrings функций. Проверка типов данных входных параметров и их преобразование самостоятельно - утомительный подход, склонный к ошибкам.

Если необходимо преобразовать входные параметры, используйте функции в этой таблице.

Преобразование

Функция

Строковый скаляр в вектор символов

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-by- n массив символов, типа данных char.

  • Символьный массив - m-by- n массив символов, типа данных char.

  • Массив ячеек из символьных векторов - Массив ячеек, в котором каждая камера содержит вектор символов.

  • Строковый или строковый скаляр - 1-by- 1 строковые массивы. Строковый скаляр может содержать 1-by- n последовательность символов, но сама является одним объектом. Используйте термины «строковый скаляр» и «вектор символов» вместе друг с другом, когда нужно быть точным о размере и типе данных. В противном случае можно использовать термин «string» в описаниях.

  • Вектор строка - 1-by- n или n-by- 1 строковые массивы. Если возможен только один размер, используйте его в описании. Для примера используйте "1-by- n строковые массивы ", чтобы описать массив такого размера.

  • Строковые массивы - m-by- n строковые массивы.

  • Пустая строка - Строковый скаляр, не содержащий символов.

  • Пустые строковые массивы - Строковые массивы с по крайней мере одной размерностью, размер которого 0.

  • Отсутствующая строка - Строковый скаляр, который является отсутствующим значением (отображается как <missing>).

См. также

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

Похожие темы