什么时候在MATLAB中通过引用进行分配?

时间:2017-03-08 06:25:13

标签: matlab variable-assignment evaluation matrix-indexing language-details

这是关于MATLAB语言的问题。我正在阅读MathWorks“Onramp”教程,我注意到一个奇怪的“按引用分配”行为(缺少一个更好的术语),这与我的期望相反。

v1 = [4 6 1 3 4 9 5];

我认为在下面,它首先计算括号表达式,它生成一个逻辑数组[1 0 1 1 1 0 0],然后索引v1得到结果。到目前为止一切都很好。

>> v1(v1 < 5)

ans =

     4     1     3     4

以下是令我惊讶的。如果你运行它,你会看到 ans (默认结果变量,一个匿名变量的类型)获取值[4 1 3 4],它是语句左侧的值。我希望赋值只能写入 ans ,而是通过引用传递并写入引用数组v1

>> v1(v1 < 5) = 1

v1 =

     1     6     1     1     1     9     5

当然,这与其他语言类似。在print a[3]中,语法意味着我们得到a[3]的值,但在a[3] = 1中,语法意味着我们为a[3]分配了一个新值。从这个意义上说,唯一的“新”部分是MATLAB允许比大多数语言更高级的索引表达式。

这里令人困惑的是,MATLAB清楚地评估了两种表达方式。 获取索引值并将其存储在ans中,但随后忽略该值并将右侧值放入索引引用的位置。

我不知道如果不对表达式进行两次评估,或者在幕后做其他魔术,它怎么能做到这一点。我不觉得自己掌握了评估的顺序/规则。

感谢您对“真正”发生的事情有所了解。

2 个答案:

答案 0 :(得分:1)

考虑你的例子的一种方式

v1(v1 < 5) = 1;

是考虑MATLAB执行的有效函数形式。在这种情况下,这个表达式由MATLAB转换为函数调用,如下所示:

v1 = subsasgn(v1, substruct('()', {v1 < 5}), 1);

换句话说,当MATLAB看到索引的赋值形式(即变量出现在=的左侧)时,内部会转换为函数调用,它们都接受原始值,并覆盖它。 (MATLAB&#34;就地优化&#34;意味着这通常是有效的,并且不会重复内存)。 substruct封装了索引形式的所有细节。如果您要分配struct字段的一部分或类似的内容,这可能会变得非常复杂。

答案 1 :(得分:0)

我认为这种说法是错误的,而这正是引起混淆的原因:

  

获取索引值并将其存储在ans

是什么让你认为在写入之前需要读取特定的内存?这些是独立的行动。

但是,当我们考虑范围时,您所说的内容可能有意义。让我们假设解释器在遇到括号(很像函数)时,使用自己的ans变量创建自己的范围,然后在完成其工作后将其丢弃。然后,我们在封闭范围内看不到这些效果。

接下来,我想详细说明TroyEdric所说的内容。

据我所知,这里的不同之处在于如何在执行之前将代码解释为内置函数。

  • 您的第一个示例v1(v1 < 5)被解释为subsref,然后隐式分配给ans。这相当于明确地编写ans = v1(v1 < 5);。这里ans是索引表达式的结果。
  • 您的第二个示例v1(v1 < 5) = 1被解释为subsasgn。这里的输出只是赋值操作后的输入。

关于运营商优先级,请参阅this文档页面。