今天我很惊讶发现
A = {1,2,3}
和
B = {1,2,3,}
都是MATLAB中的有效语法。我原以为第二个语句会产生错误。尽我所知,他们生成相同的单元格数组(all([A{:}]==[B{:}])
返回true)。
是否有理由允许使用第二种语法?这是解析器中的错误吗? A
和B
真的相同吗?
有趣的是,以下是不允许:
C = {1,2,3,,,}
答案 0 :(得分:21)
这些是更多的猜测,而不是答案。
可以检查Symbol reference并发现逗号,
可以用作
命令或声明分隔符
要在同一行输入多个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 statement - NOP用 C 写的核心,基本上意味着:什么都不做。所以在3,;
跟随三次“什么都不做”后,才会出现下一个声明。 毫无意义,正如Matlab告诉你的那样:不需要额外的分号。 - 但是有效。
它还允许你毫无意义的事情:
if true
;
end
这大概是也是
的原因C = {1,2,3,,,}
返回错误,因为逗号,
不是空语句,但在第一个逗号之后会有一个语句。
底线:它看起来很奇怪,但实际上对我来说似乎是逻辑,因为Matlab在内部使用了很多C-Code并考虑了null语句,所提到的一切都是有效的语法。
其他语言怎么样?
像Python中的x = [1,2,3,;;;;4,5,6;;;]
一样使用的半冒号即使在预期的Matlab克隆 numpy 中也是无效的,除非包含在这种不常见的语法a = np.matrix('1,2,3;4,5,6')
中。
a = np.matrix('1,2,3,;;;;4,5,6;;;')
也会抛出错误,因为;
在任何情况下都被解释为数组行分隔符,这会让编译器抱怨行不一致的行大小。
然而,
x = [1,2,3,]
也是Python
和IronPython
中的有效语法,正如VBScript
中提到的Lua
和{{1}}一样。所有这些语言有什么共同之处?它们是在运行时解释的所有(或多或少)脚本语言。这不仅仅是Matlab。因此,OP的兴奋仍然没有原因。
答案 1 :(得分:4)
许多语言已经在列表中允许一个额外的元素分隔符。但这与运行时解析无关。甚至C都允许。它与易用性有关。此功能旨在帮助用户。例如,在C中,您可以如下定义enum
:
enum E {
a,
b,
c,
};
c
之后的逗号不是必需的,但允许使用逗号。这样可以更轻松地从这样的列表中添加和删除元素,并且可以更容易地以编程方式生成这样的列表(mlepage's answer是正确的!)。
因此,在大多数(如果不是全部)编程语言中,最后都允许使用一个逗号是很常见的,MATLAB也支持它。列表开头的逗号不太有意义,但我想他们支持它,因为它也不会对它造成伤害。
连续多个逗号没有意义,这意味着还有其他未指定的元素。
但是,多个分号又是怎么回事呢?与Luis Mendo mentioned一样,[1;;2]
是合法语法。这与其他语言的确有很大的出入。
但是,这与MATLAB对换行符的使用是一致的。在MATLAB中,换行很重要。使用[]
定义数组时,换行符指示新的数据行:
M = [ 1, 2, 3,
4, 5, 6,
7, 8, 9,
];
与
相同M = [1,2,3; 4,5,6; 7,8,9];
(请注意,有时有时在每行的末尾允许逗号会很方便。)
(还要注意,我在这里使用[]
进行串联,完全相同的逻辑适用于{}
。)
但是因为MATLAB希望尽可能地允许它,只要它保持明确,上面的内容就是:
M = [ 1, 2, 3,
4, 5, 6,
7, 8, 9,
];
如果允许使用空行并没有什么坏处,为什么不允许使用空行呢?
由于每个换行符都对应一个分号,因此以上内容与以下内容相同:
M = [ 1, 2, 3,;...
4, 5, 6,;...
;...
;...
7, 8, 9,;...
];
与
相同M = [ 1, 2, 3,; 4, 5, 6,; ; ; 7, 8, 9,; ];
所以MATLAB必须能够解析它,无论它是否有意义。
该论点是,
和;
都被定义为语句分隔符,但是以某种方式假定;;;
是有效语句,而,,,
不是有效语句。这根本不是真的:
disp(0),,,disp(1)
disp(0);;;disp(1)
都是有效的MATLAB语法(R2017a解析两者都没有错误)。
此外,答案使expressions和statements感到困惑。 disp(0)
是一个声明。该语句中的0
是一个表达式。在M=[1,2,3]
中,用逗号分隔的内容是表达式,而不是语句。那里的逗号不能用作语句分隔符。
实际上,在MATLAB中,逗号和分号根据上下文具有多种含义。语句(包括空语句)末尾的逗号和分号与串联表达式([1,2;3,4]
)中的逗号和分号不同。而且逗号还可以在不允许使用分号的函数调用括号内分隔表达式。
只需阐明这一点:
1,,,4
有效,而
[1,,,4]
不是。这两个语句中的逗号具有不同的功能。
简而言之,该答案中使用的逻辑完全不正确。
答案 2 :(得分:2)
如果要从其他代码生成代码,则允许在语言中使用尾随标点符号很方便。
例如,Lua允许使用尾随逗号,因此生成Lua代码很容易。
生成代码中没有特殊情况可以省略最后一个逗号,您可以为每个项目打印ITEM-THEN-COMMA。