Ruby是按值传递还是按引用传递? [英] Is Ruby pass-by-value or pass-by-reference?

查看:181
本文介绍了Ruby是按值传递还是按引用传递?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我基本上是一名java开发人员。我在红宝石工作了大约一年。与java不同,Ruby是一种纯粹的面向对象编程语言。这是一个疑问。它是按值传递还是按引用传递? Java作为pass-by-value工作:当传递基元时,我看到值被复制并传递给方法。但是如果有对象,则引用被复制并传递给方法。引用包含对象的位置在堆中。在方法调用期间,只传递对象的位置。因此不会创建重复的对象。修改相同的对象。

I am basically a java developer. I am working in ruby for about an year. Unlike java, Ruby is a pure object oriented programming language. Here comes a doubt. Is it pass-by-value or pass-by-reference? Java works as pass-by-value: "When passing primitives, I see that the value is duplicated and passed to the method. But incase of Objects, the reference is duplicated and passed to the method. The reference contains the location of the object in the heap. During the method call, only the location of the object is passed. So no duplicate objects are created. The same object is modified."

但是当我尝试下面的ruby代码片段时,我得到的结果与我在Java中得到的结果相同:数字在一个原语中就像一个原语(比如java)方法调用,而数组作为完美的引用,如在java。现在,我很困惑。如果ruby中的所有内容都是对象,那么在方法调用期间为什么数字对象会重复?

But when I tried the below ruby code snippet, I got the same results as I got in Java: "The numbers work like a primitive (like in java) during a method call whereas the array works as perfect references like in java". Now, I am confused. If everything in ruby are objects, then why the number objects are duplicated during the method call?

class A
  def meth1(a)
    a = a+5
    puts "a inside meth1---#{a}"
  end

  def meth2(array)
    array.pop
    puts "array inside meth2---#{array}"
  end
end


obj1 = A.new
aa=5
obj1.meth1(aa)
puts "aa-----#{aa}"

arr = [3,4,5]
obj1.meth2(arr)
puts "arr---#{arr}"

结果:

a inside meth1 --- 10

a inside meth1---10

aa ----- 5

aa-----5

在meth2里面的数组--- 34

array inside meth2---34

arr --- 34

arr---34

推荐答案

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

Ruby uses pass-by-value, or more precisely, a special case of pass-by-value where the value being passed is always a pointer. This special case is also sometimes known as call-by-sharing, call-by-object-sharing or call-by-object.

这与使用的约定相同通过Java(用于对象),C#(默认情况下用于引用类型),Smalltalk,Python,ECMAScript / JavaScript以及或多或少的所有面向对象语言。

It's the same convention that is used by Java (for objects), C# (by default for reference types), Smalltalk, Python, ECMAScript/JavaScript and more or less every object-oriented language ever created.

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

Note: on all existing Ruby implementations Symbols, Fixnums and Floats are actually passed directly by value and not with an intermediary pointer. However, since those three are immutable, there is no observable behavioral difference between pass-by-value and call-by-object-sharing in this case, so you can greatly simplify your mental model by simply treating everything as call-by-object-sharing. Just interpret these three special cases as internal compiler optimizations that you don't need to worry about.

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

Here's a simple example you can run to determine the argument passing convention of Ruby (or any other language, after you translate it):

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!'

这篇关于Ruby是按值传递还是按引用传递?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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