29

在 Ruby 中,是否可以通过引用传递具有值类型语义的参数(例如 Fixnum)?我正在寻找类似于 C# 的 ' ref ' 关键字的东西。

例子:

def func(x) 
    x += 1
end

a = 5
func(a)  #this should be something like func(ref a)
puts a   #should read '6'

顺便提一句。我知道我可以使用:

a = func(a)
4

6 回答 6

32

您可以通过显式传入当前绑定来完成此操作:

def func(x, bdg)
  eval "#{x} += 1", bdg
end

a = 5
func(:a, binding)
puts a # => 6
于 2008-10-02T10:06:23.247 回答
20

Ruby 根本不支持“按引用传递”。一切都是对象,对这些对象的引用总是按值传递。实际上,在您的示例中,您Fixnum通过值传递了对 Object 的引用的副本。

您的代码的问题是,它x += 1不会修改传递的Fixnum对象,而是创建一个全新的独立对象。

我认为,Java 程序员会称Fixnum对象为不可变的。

于 2008-10-02T10:00:40.033 回答
12

在 Ruby 中,您不能通过引用传递参数。对于您的示例,您必须返回新值并将其分配给变量 a 或创建一个包含该值的新类并传递此类的实例。例子:

class Container
attr_accessor :value
 def initialize value
   @value = value
 end
end

def func(x)
  x.value += 1
end

a = Container.new(5)
func(a)
puts a.value
于 2008-10-02T10:13:23.933 回答
8

您可以尝试以下技巧:

def func(x) 
    x[0] += 1
end

a = [5]
func(a)  #this should be something like func(ref a)
puts a[0]   #should read '6'
于 2015-03-02T07:01:33.843 回答
2

http://ruby-doc.org/core-2.1.5/Fixnum.html

Fixnum 对象具有直接的价值。这意味着当它们被分配或作为参数传递时,传递的是实际对象,而不是对该对象的引用。

Ruby也是按值传递的

于 2016-03-02T06:53:26.073 回答
-1

但是,复合对象(如哈希)似乎是通过引用传递的:

fp = {}
def changeit(par)
  par[:abc] = 'cde'
end

changeit(fp)

p fp

{:abc=>"cde"}
于 2019-05-16T12:08:34.733 回答