Подтвердить что ты не робот

Почему конечная запятая в массиве ячеек имеет синтаксис Matlab?

Сегодня я был удивлен, обнаружив, что

A = {1,2,3}

и

B = {1,2,3,}

- оба действительных синтаксиса в MATLAB. Я бы ожидал, что второе утверждение даст ошибку. Насколько я могу судить, они производят идентичные массивы ячеек (all([A{:}]==[B{:}]) возвращает true).

Есть ли причина, по которой разрешен второй синтаксис? Это ошибка в парсере? Значения A и B действительно одинаковы?

Интригующе, не допускается следующее:

C = {1,2,3,,,}
4b9b3361

Ответ 1

Это скорее догадки, чем ответ.

Можно проверить Символьный справочник и найти, что запятая , может использоваться как

Сепаратор команд или операторов

Чтобы ввести несколько команд или операторов MATLAB в одной строке, отделяйте каждую команду или инструкцию запятой:

for k = 1:10, sum(A(k)), end

В строке

B = {1,2,3,}

поэтому ожидается утверждение после 3, существует только }, что означает конец массива ячеек, действительный оператор.


точка с запятой ; имеет три официальных использования:

Сепаратор строк массива

При использовании в квадратных скобках для создания нового массива или конкатенации существующие массивы, точка с запятой создает новую строку в массиве:

A = [5, 8; 3, 4]

Подавление вывода

При размещении в конце команды точка с запятой сообщает MATLAB не отобразить любой вывод из этой команды. В этом примере MATLAB не отобразите полученную матрицу размером 100 на 100:

A = ones(100, 100);

Сепаратор команд или операторов

Как и оператор запятой, вы можете ввести более одной команды MATLAB на строка, разделив каждую команду точкой с запятой. MATLAB подавляет вывода для тех команд, которые заканчиваются точкой с запятой, и отображает вывод для команд, заканчивающихся запятой.

В этом примере присваивания переменным A и C завершаются точка с запятой и, следовательно, не отображаются. Поскольку назначение B является с запятой, вывод этой команды отображается:

A = 12.5; B = 42.7, C = 1.25;

Итак, в строке

x = {1,2,3,;5,6,7}

он следует за допустимым выражением Сепаратор строк массива после 3,. Впоследствии ожидается новое утверждение, которое в данном случае является двойным 5. Действительно.


Теперь рассмотрим случай

x = {1,2,3,;;;;4,5,6;;;}

Как указано выше после 3, следует оператор Разделитель строк массива, и утверждение после этого предположительно является null - NOP, взятый из основного ядра программы, написанного в C, что в основном означает: ничего не делать. Поэтому после 3,; следует три раза "ничего не делать" , прежде чем наступит следующий оператор. Не имеет смысла, как говорит вам Матлаб: лишняя точка с запятой не нужна. - , но действителен.

Это также позволяет использовать бессмысленные вещи, например:

if true
    ;
end

И это, по-видимому, также причина, по которой

C = {1,2,3,,,} 

возвращает ошибку, потому что запятая , не является оператором null, но после первой запятой есть ожидаемое утверждение.


В нижней строке: это выглядит странно, но на самом деле кажется логичным для меня, поскольку Matlab использует много C-кода внутри и рассматривает оператор null, все упомянутое является допустимым синтаксисом.


Как насчет других языков?

Полуколоны, используемые как x = [1,2,3,;;;;4,5,6;;;] в Python, являются недопустимыми даже в предполагаемом клоне Matlab numpy, если они не включены в этот необычный синтаксис a = np.matrix('1,2,3;4,5,6').

a = np.matrix('1,2,3,;;;;4,5,6;;;')

также выдаст ошибку, поскольку ; интерпретируется как Array Row Separator в любом случае, что заставляет компилятор жаловаться на несоответствующие размеры строк.

Однако

x = [1,2,3,]

также действительный синтаксис в Python и IronPython, как и в VBScript и Lua, как указано в ответ mlepage. Что общего у всех этих языков? Это все (более или менее) языки сценариев, интерпретируемые во время выполнения. Это не только Матлаб. Таким образом, волнение ОР остается без причины.

Ответ 2

Удобно разрешить прерывание пунктуации на языках, если код будет создан из другого кода.

Например, Lua разрешает запятые, поэтому легко генерировать код Lua.

У вас нет специального случая, чтобы генерирующий код опускал последнюю запятую, вы можете просто распечатать ITEM-THEN-COMMA для каждого элемента.