Ruby 通过引用传递参数

Ruby 通过引用传递参数,ruby,Ruby,因为变量foo和bar在这个类中可能会一起修改很多次,所以我想知道是否可以使用一种方法来完成这项工作。我想在方法print中打印2,0,而在上述代码中我仍然得到1,1。有没有一种简单的方法可以在Ruby中编写这样的方法?是否可以这样做 class Test def initialize @foo = 1 @bar = 1 end def change(a, b) a += 1 b -= 1 end def print chan

因为变量
foo
bar
在这个类中可能会一起修改很多次,所以我想知道是否可以使用一种方法来完成这项工作。我想在方法
print
中打印
2,0
,而在上述代码中我仍然得到
1,1
。有没有一种简单的方法可以在Ruby中编写这样的方法?

是否可以这样做

class Test
  def initialize
    @foo = 1
    @bar = 1
  end
  def change(a, b) 
    a += 1
    b -= 1   
  end 
  def print
    change(@foo,@bar)
    puts "#{@foo},#{@bar}"
  end
end
您可以在Ruby中执行类似的操作,但它更高级,因为不内置按引用传递


这将导致更难理解源代码。具有意外的副作用。

整数在Ruby中是不可变的对象,因此不能以这种方式修改它们
a+=1
只需将局部变量
a
重新赋值为新值,它不会修改原始对象(1)

为了实现你想要的(尽管你没有真正解释你想要什么),你有几种可能性:

  • 在对象中包装整数(对于这样一个简单的示例来说,这很麻烦)

  • 使用可变对象而不是整数,例如哈希

例如:

class Test
  def initialize
    @foo = 1
    @bar = 1
  end
  def change(a, b) 
    a += 1
    b -= 1
    [a, b]   
  end 
  def print
    @foo, @bar = change(@foo,@bar)
    puts "#{@foo},#{@bar}"
  end
end

还有一点需要注意:很少有人需要将对象的实例变量作为参数传递给同一对象的方法(
change(@foo,@bar)
)。实例变量用于保持对象的内部状态。

Ruby实际上可以做到这一点,但它并不像您想象的那么清晰。在Ruby中,所有变量都只是对对象的引用。因此:

class Test
  def initialize
    @foo_bar = { foo: 1, bar: 1 }
  end
  def change(a, b) 
    @foo_bar[a] += 1
    @foo_bar[b] -= 1
  end 
  def print
    change(:foo,:bar)
    puts "#{@foo_bar[:foo]},#{@foo_bar[:bar]}"
  end
end
2.0.0p0:001>def m(a)
2.0.0p0:002?>a
2.0.0p0:004?>结束
=>零
2.0.0p0:005>a=[3,2]
=> [3, 2]
2.0.0p0:006>m(a)
=> [3, 2, 1]
2.0.0p0:007>a
=> [3, 2, 1]
但是,整数是不可变的。所以,对于整型变量,你不能做同样的事情。你看,+=、-=、*=,等等,实际上都是
var=var+/-/*rhs
。这只修改存储在局部变量中的引用,而不修改传递的变量中的引用。您确实有两种选择:


  • 使用可变对象:使用散列、数组等,并确保使用破坏性操作,如
    为什么您认为原始值不会更改?你能更详细地介绍一下你想要实现的目标吗?我已经更新了我的程序:)通常你不想这样通过引用传递。这仍然不能说明你想要做什么。你想解决什么问题?我想做的是写一个方法,可以修改它的参数值,让调用者能够看到修改。假设有另一个变量
    @abc
    。调用
    change(@foo,@abc)
    后,我希望调用者看到
    @foo
    的值加1。同样适用于
    @abc
    2.0.0p0 :001 > def m(a)
    2.0.0p0 :002?>   a << 1
    2.0.0p0 :003?>   a
    2.0.0p0 :004?> end
     => nil
    2.0.0p0 :005 > a = [3,2]
     => [3, 2]
    2.0.0p0 :006 > m(a)
     => [3, 2, 1]
    2.0.0p0 :007 > a
     => [3, 2, 1]