将对象传递给方法时创建/引用的内存是什么?

时间:2012-09-07 18:08:08

标签: ruby memory-management

  

可能重复:
  Is Ruby pass by reference or by value?

使用Ruby,在将对象传递给方法时,如何处理此对象的内存?

来自C背景,我可以想到可能发生的一些事情:

  1. 与相应对象关联的内存副本,可供调用的方法使用。在这种情况下,对象的修改只会反映在被调用方法的上下文中,并且不是调用方法。

  2. 对对象内存的引用传递给被调用的方法(本质上是一个指针)。因此,被调用的方法或调用方法对对象所做的任何更改都将反映在两个上下文中。同样,如果该程序是多线程的,则必须使用某种机制(互斥,信号量等)来确保对执行写操作的内存进行互斥访问。

  3. 我无法想到的其他内容......也许是类似于Go的内存模型......管道...... MessagePassing ......?

  4. 实际发生了什么?

2 个答案:

答案 0 :(得分:2)

Ruby使用第二个选项,通过引用传递参数。

答案 1 :(得分:2)

Ruby使用pass-by-value,或者更确切地说,是一个传递值的特殊情况,其中传递的值是总是一个指针。这种特殊情况有时也称为分享呼叫,按对象分享或逐个呼叫。

与所创建的每种面向对象语言或多或少使用的约定相同。

注意:在所有现有的Ruby实现Symbol上,FixnumFloat实际上是按直接传递的,而不是带有中间指针。但是,由于这三个是不可变的,在这种情况下,传值和对象共享之间没有可观察到的行为差异,因此您可以通过简单地处理所有内容来大大简化您的心理模型作为逐个对象分享。只需将这三种特殊情况解释为内部编译器优化,您无需担心。

这是一个简单的例子,您可以运行以确定传递Ruby(或任何其他语言,在您翻译之后)的约定的参数:

def is_ruby_pass_by_value?(foo)
  foo.replace('More precisely, it is call-by-object-sharing!')
  foo = 'No, Ruby is pass-by-reference.'
  return nil
end

bar = 'Yes, of course, Ruby *is* pass-by-value!'

is_ruby_pass_by_value?(bar)

p bar
# 'More precisely, it is call-by-object-sharing!'

简而言之:这是你的选择2.