Ruby - 参考引用或值?

时间:2014-04-03 03:56:13

标签: ruby

我不明白为什么他们say Ruby按值传递所有参数,同时下面的代码证明了相反:

class MyClass1
  @var1 = 123

  def get1
    @var1
  end

  def set1=value
    @var1 = value
  end
end

c1 = MyClass1.new
c1.set1 = 444
p c1.get1 # 444

def test1 mc
  mc.set1 = 999
end

test1 c1
p c1.get1 # 999

如果按值计算,则会打印出444,而不是999

1 个答案:

答案 0 :(得分:64)

这个问题让人感到困惑,因为有一种叫做引用类型的东西,并且有一种叫做pass-by-reference的东西,但它们实际上并没有那么多关于彼此。

引用的引用,值和值:A(sorta)简要概述

在传递引​​用方案中,函数的参数是对传递给函数的变量的引用,修改参数会修改原始变量。 这不是Ruby的原因。例如,让我们看一下以下代码:

def inc(val)
  val += 1
end

a = 1
inc a
puts a

如果Ruby是传递引用语言,则此程序将打印2,因为val += 1中的inc会增加a的值。但事实并非如此。变量val不是对变量a的引用 - 它是一个给定相同值的自变量。

“但是等等!”你说。 “如果我们处理对象怎么办?肯定是通过引用传递对象变量,对吗?”

不。

def change_string(str)
  str << " I can insult you all you want"
  str << " because you'll never see this"
  str << " because I'm going to replace the whole string!"
  str << " Haha you smell bad!"
  str = "What? I didn't say anything." # I'm so sneaky
end

be_nice_to_me = "hello"
change_string(be_nice_to_me)
puts be_nice_to_me

如果Ruby是通过引用传递的,那么你永远不会看到change_string方法的意义,因为str = "What, I didn't say anything."将完全用be_nice_to_me替换字符串"What? I didn't say anything." {1}}但事实上change_string的罪行是敞开的,所有人都可以看到。如果Ruby没有通过引用传递,这怎么可能?

那么,还记得我之前谈过的引用类型吗?嗯,这就是Ruby中的对象。引用类型是一种类型,其值是对其他内容的引用。在这种情况下,变量的值是对字符串"hello"的引用。传递字符串时,变量的值(即引用)将复制到变量str中。所以现在他们都持有对同一个对象的引用,但str不是对be_nice_to_me的引用。因此,当您修改对象时,会显示这些更改,因为它们都指向同一个对象。但是当你修改一个变量时,另一个变量看不到它,因为这两个变量都不是对另一个变量的引用

Ruby传递引用还是按值传递?它是值传递,但所有值都是引用。