MATLAB变量传递和延迟分配 [英] MATLAB variable passing and lazy assignment

查看:172
本文介绍了MATLAB变量传递和延迟分配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道在Matlab中,将新变量分配给现有变量时会出现惰性"评估.如:

I know that in Matlab, there is a 'lazy' evaluation when a new variable is assigned to an existing one. Such as:

array1 = ones(1,1e8);
array2 = array1;

除非修改array2的元素,否则不会将array1的值复制到array2.

The value of array1 won't be copied to array2 unless the element of array2 is modified.

据此,我认为Matlab中的所有变量实际上都是值类型,并且都按值传递(尽管使用了惰性求值).这也意味着这些变量是在调用堆栈上创建的.

From this I supposed that all the variables in Matlab are actually value-type and are all passed by values (although lazy evaluation is used). This also implies that the variables are created on the call stack.

嗯,尽管我从未见过使用第二种编程语言来执行此操作,但我尚未判断它对待变量的方式.我的意思是,对于可能较大的数据结构(例如数组),将其视为值类型并按值传递它似乎不是一个好主意.尽管懒惰的评估节省了时间和空间,但对我来说似乎很奇怪.您可能有一个表达式,该变量用于导致变量(而不是初始化或赋值)而导致内存不足错误.据我所知,在C数组名称实际上是指针,而在Fortran中,数组是通过引用传递的.大多数现代语言都将数组作为参考类型撤回.

Well, I am not judging the way it treats the variables, although I have never seen a second programming language doing this way. I mean, for possibly large data structures such as arrays, treating it as value type and passing it by values does not seem to be a good idea. Though the lazy evaluation saves the space and time, it just seems strange to me. You may have an expression for mutating (instead of initialization or assignment) of a variable leading to an out-of-memory error. As far as I know, in C array names are actually pointers, and in Fortran, arrays are passed by reference. Most modern languages retreat arrays as reference type.

因此,谁能告诉我Matlab为什么使用这种不太常见的方式来实现数组.在Matlab中,在堆上什么也不可以创建什么是真的吗?

So, can anyone tell me why Matlab use such a not-so-common way to implement the arrays. Is it true that in Matlab, nothing is or can be created on the heap?

顺便说一句,我已经问过一些有经验的Matlab用户.他们只是简单地说,一旦创建变量就永远不会更改,而使用函数调用来创建新变量.这意味着所有可变数据都被视为不可变的.通过这种方式进行编程会带来任何收益或损失吗?

By the way, I have asked some experienced Matlab users about it. They simply say that they never change the variable once it is created, and use function call to create new variables. That means all the mutable data are treated immutable. Is there any gain or loss for programming in this way?

推荐答案

您正在以一种令人困惑的方式措辞您的问题,使用来自诸如C和FORTRAN的编程语言的术语,这些术语在应用于其他语言时会产生误导.

You're phrasing your question in a confusing way, using terms from programming languages such as C and FORTRAN that are misleading when applied to other languages.

按值传递按引用的变量与具有值语义引用语义的变量.

在C语言中,变量可以按值传递,也可以使用指针通过引用传递.

In C, variables can be passed by value, or they can be passed by reference using a pointer.

MATLAB没有指针.无论如何,MATLAB总是按值传递变量.由于它没有指针,因此问它是按值传递值还是按引用传递变量都没有意义-它必须按值传递.

MATLAB does not have pointers. Whatever you've been told, MATLAB always passes variables by value. Since it does not have pointers, it doesn't make sense to ask whether it is passing variables by value or by reference - it must be by value.

尽管如此,MATLAB变量可以具有值语义引用语义.在MATLAB中,具有参考语义的变量称为 handle 变量.

Nevertheless, MATLAB variables can have either value semantics or reference semantics. In MATLAB, a variable with reference semantics is called a handle variable.

要强调-即使变量通过值传递,它也可以具有值或引用语义.

To emphasise - even if the variable is being passed by value, it can have either value or reference semantics.

创建常规变量时:

>> a = 1;

变量a具有值语义.这意味着如果您从中创建另一个变量然后更改原始变量,则新变量不会更改.

The variable a has value semantics. What this means is that if you create another variable from it and then change the original, the new variable does not change.

>> b = a;
>> b
b =
     1
>> a = 2;
>> b
b =
     1

但是,例如,如果创建一个图形:

But if you create, for example, a figure:

>> f = figure;

变量f具有引用或处理语义.这意味着如果您从中创建另一个变量然后更改原始变量,则新变量也会更改.

The variable f has reference, or handle semantics. What this means is that if you create another variable from it and then change the original, the new variable also changes.

>> get(f, 'Name')
ans =
     ''
>> g = f;
>> set(f, 'Name', 'hello')
>> get(g, 'Name')
ans =
hello

使用MATLAB OO类定义自己的变量类型时,可以通过从内置类handle继承该类来指定该类的对象是具有值还是引用/句柄语义.

When you define your own variable types using MATLAB OO classes, you can specify whether the objects of that class will have value or reference/handle semantics by inheriting the class from the built-in class handle.

作为值类实例的对象的行为与上面的a类似;作为句柄类实例的对象的行为将与上面的f相似. 而且,它们两者总是按值传递的.

Objects that are instances of value classes will behave similarly to a above; objects that are instances of handle classes will behave similarly to f above. And they are both, always, passed by value.

我正在猜测这个问题的根本原因:但是我建议您研究一下如何创建句柄类.它们可能会为您提供您希望实现的可变行为(即,能够传递它,在不显着增加内存的情况下获取它的副本,并且始终引用相同的底层内容).

I'm guessing at the underlying reason for your question: but I would recommend that you take a look into how to create handle classes. They will probably provide you with the variable behaviour that you're hoping to achieve (i.e. being able to pass it around, take a copy of it without increasing memory significantly, and it always refers to the same underlying thing).

如果您所说的有经验的MATLAB用户"仅使用值变量,那么他们将损失很多-使用句柄变量通常会更方便.实际上,我敢打赌,他们在使用它们时并未意识到它-几乎所有的MATLAB Handle Graphics都依赖于句柄变量,例如上面的f.

If the "experienced MATLAB users" you have spoken to are using only value variables then they are losing a great deal - it is very often much more convenient to use handle variables. And I would actually bet that they are using them without realising it - pretty much all of MATLAB Handle Graphics relies on handle variables, like f above.

我相信以上内容是对MATLAB变量语义的完整解释.还有其他一些使人困惑的皱纹,但它们与以上所述并不矛盾:

I believe the above is a complete explanation of the semantics of MATLAB variables. There are a couple of other wrinkles that confuse people, but they do not contradict the above:

  1. 尽管MATLAB具有传递值行为(如上所述,该行为不同于变量具有值语义还是引用语义),但它也具有 lazy copy-写行为.您在问题中对此进行了描述,因此很显然您可以了解其作用,但这只是一种优化,与传递行为或变量语义无关.

  1. Although MATLAB has pass-by-value behaviour (which, as explained above is different from whether variables have value or reference semantics), it also has lazy or copy-on-write behaviour. You describe this in your question, so you obviously get what it's doing, but it's simply an optimization that is a separate issue from the passing behaviour or variable semantics.

如@Bernhard的评论中所述,如果您使用类似于x = myfun(x)的语法而不是更普通的y = myfun(x)来实现函数,则MATLAB可以对代码执行就地优化(即覆盖代码).在某些情况下(尤其是在myfun中在x上执行的操作)必须能够就地完成,例如算术或三角函数,而不是矩阵运算,例如'会更改尺寸).但是,这只是一个优化,它不会更改变量的语义.

As mentioned in a comment by @Bernhard, if you implement functions using a syntax similar to x = myfun(x) rather than the more normal y = myfun(x), MATLAB can perform in-place optimizations on your code (i.e. overwriting the original variable rather than making a temporary copy) in some circumstances (in particular, the operations carried out on x within myfun have to be capable of being done in-place, such as arithmetic or trigonometric functions, not matrix operations like ' that would change the dimensions). But again, this is just an optimization, it doesn't change the semantics of the variables.


PS还有一件事-不再考虑堆栈和堆;在MATLAB中并没有真正的模拟物,因为您实际上无法控制变量存储在哪个内存区域.


PS One more thing - stop thinking about the stack and the heap as well; there's not really an analogue in MATLAB, because you don't really have control over what area of memory your variables are stored in.

这篇关于MATLAB变量传递和延迟分配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆