【问题标题】:Why is a trailing comma in a cell array valid Matlab syntax?为什么单元格数组中的尾随逗号是有效的 Matlab 语法?
【发布时间】:2015-09-29 16:59:12
【问题描述】:

今天我很惊讶地发现

A = {1,2,3}

B = {1,2,3,}

都是 MATLAB 中的有效语法。我本来预计第二个语句会产生错误。据我所知,它们产生相同的元胞数组(all([A{:}]==[B{:}]) 返回 true)。

允许使用第二种语法有什么原因吗?这是解析器中的错误吗? AB 真的一样吗?

有趣的是,不允许以下内容:

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

【问题讨论】:

  • 有趣。 {1,2,4,;;;;4,5,6;;;} 也允许
  • @LuisMendo 真正让我感到奇怪的是它最终变成了一个漂亮、紧凑的矩形。似乎那里至少应该有一些空行之类的......
  • B={1,2,3,} 是滥用,但 {1,2,4,;;;;4,5,6;;;} 只是邪恶的
  • 但至少 Matlab 让你知道它是 unneccssary ;)
  • @thewaywewalk,我最讨厌的是它警告我 str2numstr2double 慢或类似的东西。如果我想要 STR2DOUBLE,我会使用 STR2DOUBLE,你是 IDE 的蹩脚借口!!!

标签: arrays matlab syntax operators cell-array


【解决方案1】:

这些都是猜测,而不是答案。

可以查看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, 之后的有效语句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,,,} 

返回错误,因为逗号 , 不是 null 语句,但在第一个逗号之后应该有一个语句。


底线:这看起来很奇怪,但实际上对我来说似乎很合乎逻辑,因为 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;;;')

也会抛出错误,因为; 在任何情况下都会被解释为Array Row Separator,这会使编译器抱怨行大小不一致。

然而,

x = [1,2,3,]

PythonIronPython 中也是有效的语法,就像在mlepage's answer 中提到的VBScriptLua 中一样。所有这些语言有什么共同点?它们都是(或多或少)在运行时解释的脚本语言。这不仅仅是 Matlab。因此,OP 的兴奋仍然没有理由。

【讨论】:

  • 这真的很有意义。感谢您的解释。 +1。
  • 我很想把这个 The MathWorks 的方式扔掉,看看他们是否会回答!
  • 我不认为这是正确的逻辑。我在my answer的底部解释了原因。
【解决方案2】:

如前所述,许多语言允许在列表中使用一个额外的元素分隔符。但这与运行时解析无关。甚至 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 必须能够解析它,无论它是否有意义。


反驳thewaywewalk's answer

争论是,; 都被定义为语句分隔符,但不知何故假设;;; 是一个有效的语句而,,, 不是。这根本不是真的:

disp(0),,,disp(1)
disp(0);;;disp(1)

都是有效的 MATLAB 语法(R2017a 解析两者都没有错误)。

此外,答案混淆了expressionsstatementsdisp(0) 是一个声明。该语句中的0 是一个表达式。在M=[1,2,3] 中,用逗号分隔的东西是表达式,而不是语句。那里的逗号不能用作语句分隔符。

事实上,在 MATLAB 中,逗号和分号有多种含义,具体取决于上下文。语句(包括空语句)末尾的逗号和分号与连接表达式 ([1,2;3,4]) 中的逗号和分号不同。并且逗号还可以分隔函数调用的括号内的表达式,其中不允许使用分号。

只是为了说明这一点:

1,,,4

有效,而

[1,,,4]

不是。逗号在这两个语句中的作用不同。

简而言之,该答案中使用的逻辑根本不正确。

【讨论】:

  • 我从来没有说过 1,,,4 在数组之外是无效的,所以我不明白为什么我对 OPs 案例的逻辑是不正确的,因为它显然不是......关于其他点,我说得很清楚,我只是在猜测,所以欢迎每一次深刻的纠正;)
  • @thewaywewalk:我想我解释为“因为逗号 , 不是空语句,但在第一个逗号之后有一个预期的语句”。对不起,如果我误解了你的文字。 :)
【解决方案3】:

如果要从其他代码生成代码,则允许在语言中使用尾随标点符号会很方便。

例如,Lua 允许尾随逗号,因此很容易生成 Lua 代码。

您不必在生成代码中有特殊情况来省略最后的逗号,您可以为每个项目打印 ITEM-THEN-COMMA。

【讨论】:

  • @Wolfie:为什么不呢?这对我来说似乎是正确的推理。请注意,大多数(全部?)编程语言都允许这样做,不仅用于以编程方式生成代码,而且还可以轻松编辑源代码中的数据。
  • @Cris 我什至不记得以前读过这个问题,评论被删除,似乎是一个公平的答案!一定是糟糕的一天......
猜你喜欢
  • 2011-12-21
  • 2019-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-26
  • 2021-11-20
相关资源
最近更新 更多