为什么元胞数组中的尾随逗号是有效的 Matlab 语法?
Why is a trailing comma in a cell array valid Matlab syntax?
今天我很惊讶地发现
A = {1,2,3}
和
B = {1,2,3,}
都是 MATLAB 中的有效语法。我本以为第二条语句会产生错误。据我所知,它们生成相同的元胞数组(all([A{:}]==[B{:}])
returns true)。
是否有允许第二种语法的原因?这是解析器中的错误吗? A
和B
真的一样吗?
有趣的是,以下是不允许的:
C = {1,2,3,,,}
这些是更多的猜测,而不是答案。
可以检查 Symbol reference 并发现 逗号 ,
可以用作
命令或语句分隔符
To enter more than one MATLAB command or statement on the same line,
separate each command or statement with a comma:
for k = 1:10, sum(A(k)), end
在行
B = {1,2,3,}
因此在 3
之后需要一个语句,只有 }
,这意味着 元胞数组结束 ,一个有效的语句。
分号;
官方有3种用法:
数组行分隔符
When used within square brackets to create a new array or concatenate
existing arrays, the semicolon creates a new row in the array:
A = [5, 8; 3, 4]
输出抑制
When placed at the end of a command, the semicolon tells MATLAB not to
display any output from that command. In this example, MATLAB does not
display the resulting 100-by-100 matrix:
A = ones(100, 100);
命令或语句分隔符
Like the comma operator, you can enter more than one MATLAB command on
a line by separating each command with a semicolon. MATLAB suppresses
output for those commands terminated with a semicolon, and displays
the output for commands terminated with a comma.
In this example, assignments to variables A and C are terminated with
a semicolon, and thus do not display. Because the assignment to B is
comma-terminated, the output of this one command is displayed:
A = 12.5; B = 42.7, C = 1.25;
所以在行
x = {1,2,3,;5,6,7}
它在 3,
之后跟在有效语句 Array Row Separator 之后。之后需要一个新语句,在本例中是双 5。有效。
现在考虑案例
x = {1,2,3,;;;;4,5,6;;;}
如上3,
后面的语句Array Row Separator,后面的语句推测是null statement - NOP 借用了一些用C 编写的底层程序核心,其基本意思是:什么都不做。所以在 3,;
之后跟了三次 "do nothing",然后才有下一条语句。 没有意义,正如 Matlab 告诉您的那样:不需要额外的分号。 - 但是有效。
它还允许你做一些毫无意义的事情,比如:
if true
;
end
这就是大概也是
的原因
C = {1,2,3,,,}
returns 一个错误,因为逗号 ,
不是 空语句 ,但在第一个逗号之后有一个预期的语句。
底线:它看起来很奇怪,但实际上对我来说似乎是合乎逻辑的,因为 Matlab 在内部使用了大量 C 代码并考虑到 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
中也是如此,在 中提到。所有这些语言有什么共同点?它们都是(或多或少)在运行时解释的脚本语言。不仅仅是 Matlab。因此,OP 的兴奋仍然没有理由。
如果要从其他代码生成代码,允许尾随标点符号很方便。
例如,Lua允许尾随逗号,因此很容易生成Lua代码。
您不必在生成代码中有特殊情况来省略最后的逗号,您只需为每个项目打印 ITEM-THEN-COMMA。
如前所述,许多语言允许在列表中使用一个额外的元素分隔符。但这与 运行 时间解析无关。甚至 C 也允许。它与易用性有关。这是一项旨在帮助用户的功能。例如,在 C 中你可以定义一个 enum
如下:
enum E {
a,
b,
c,
};
c
后的逗号不是必须的,但是允许的。它使得在这样的列表中添加和删除元素变得更容易,并且更容易以编程方式生成这样的列表( 是正确的!)。
因此,在大多数(如果不是全部)编程语言中,允许在末尾添加一个逗号是很常见的,MATLAB 支持它也是有意义的。列表开头的附加逗号意义不大,但我猜他们支持它,因为它也没有坏处。
连续多个逗号没有意义,这意味着还有未指定的其他元素。
那么多个分号是怎么回事呢?由于 ,[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 and statements。 disp(0)
是一个声明。该语句中的 0
是一个表达式。在M=[1,2,3]
中,逗号分隔的是表达式,不是语句。那里的逗号不能用作语句分隔符。
事实上,在 MATLAB 中,逗号和分号具有多种含义,具体取决于上下文。语句末尾的逗号和分号(包括空语句)不同于连接表达式 ([1,2;3,4]
) 中的逗号和分号。逗号还可以分隔函数调用括号内的表达式,其中不允许使用分号。
为了说明这一点:
1,,,4
有效,而
[1,,,4]
不是。逗号在这两个语句中有不同的作用。
简而言之,该答案中使用的逻辑完全不正确。
今天我很惊讶地发现
A = {1,2,3}
和
B = {1,2,3,}
都是 MATLAB 中的有效语法。我本以为第二条语句会产生错误。据我所知,它们生成相同的元胞数组(all([A{:}]==[B{:}])
returns true)。
是否有允许第二种语法的原因?这是解析器中的错误吗? A
和B
真的一样吗?
有趣的是,以下是不允许的:
C = {1,2,3,,,}
这些是更多的猜测,而不是答案。
可以检查 Symbol reference 并发现 逗号 ,
可以用作
命令或语句分隔符
To enter more than one MATLAB command or statement on the same line, separate each command or statement with a comma:
for k = 1:10, sum(A(k)), end
在行
B = {1,2,3,}
因此在 3
之后需要一个语句,只有 }
,这意味着 元胞数组结束 ,一个有效的语句。
分号;
官方有3种用法:
数组行分隔符
When used within square brackets to create a new array or concatenate existing arrays, the semicolon creates a new row in the array:
A = [5, 8; 3, 4]
输出抑制
When placed at the end of a command, the semicolon tells MATLAB not to display any output from that command. In this example, MATLAB does not display the resulting 100-by-100 matrix:
A = ones(100, 100);
命令或语句分隔符
Like the comma operator, you can enter more than one MATLAB command on a line by separating each command with a semicolon. MATLAB suppresses output for those commands terminated with a semicolon, and displays the output for commands terminated with a comma.
In this example, assignments to variables A and C are terminated with a semicolon, and thus do not display. Because the assignment to B is comma-terminated, the output of this one command is displayed:
A = 12.5; B = 42.7, C = 1.25;
所以在行
x = {1,2,3,;5,6,7}
它在 3,
之后跟在有效语句 Array Row Separator 之后。之后需要一个新语句,在本例中是双 5。有效。
现在考虑案例
x = {1,2,3,;;;;4,5,6;;;}
如上3,
后面的语句Array Row Separator,后面的语句推测是null statement - NOP 借用了一些用C 编写的底层程序核心,其基本意思是:什么都不做。所以在 3,;
之后跟了三次 "do nothing",然后才有下一条语句。 没有意义,正如 Matlab 告诉您的那样:不需要额外的分号。 - 但是有效。
它还允许你做一些毫无意义的事情,比如:
if true
;
end
这就是大概也是
的原因C = {1,2,3,,,}
returns 一个错误,因为逗号 ,
不是 空语句 ,但在第一个逗号之后有一个预期的语句。
底线:它看起来很奇怪,但实际上对我来说似乎是合乎逻辑的,因为 Matlab 在内部使用了大量 C 代码并考虑到 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
中也是如此,在
如果要从其他代码生成代码,允许尾随标点符号很方便。
例如,Lua允许尾随逗号,因此很容易生成Lua代码。
您不必在生成代码中有特殊情况来省略最后的逗号,您只需为每个项目打印 ITEM-THEN-COMMA。
如前所述,许多语言允许在列表中使用一个额外的元素分隔符。但这与 运行 时间解析无关。甚至 C 也允许。它与易用性有关。这是一项旨在帮助用户的功能。例如,在 C 中你可以定义一个 enum
如下:
enum E {
a,
b,
c,
};
c
后的逗号不是必须的,但是允许的。它使得在这样的列表中添加和删除元素变得更容易,并且更容易以编程方式生成这样的列表(
因此,在大多数(如果不是全部)编程语言中,允许在末尾添加一个逗号是很常见的,MATLAB 支持它也是有意义的。列表开头的附加逗号意义不大,但我猜他们支持它,因为它也没有坏处。
连续多个逗号没有意义,这意味着还有未指定的其他元素。
那么多个分号是怎么回事呢?由于 [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 and statements。 disp(0)
是一个声明。该语句中的 0
是一个表达式。在M=[1,2,3]
中,逗号分隔的是表达式,不是语句。那里的逗号不能用作语句分隔符。
事实上,在 MATLAB 中,逗号和分号具有多种含义,具体取决于上下文。语句末尾的逗号和分号(包括空语句)不同于连接表达式 ([1,2;3,4]
) 中的逗号和分号。逗号还可以分隔函数调用括号内的表达式,其中不允许使用分号。
为了说明这一点:
1,,,4
有效,而
[1,,,4]
不是。逗号在这两个语句中有不同的作用。
简而言之,该答案中使用的逻辑完全不正确。