ruby传参之引用类型


ruby是完全面向对象语言,所有的变量所储存的,其实是对象的引用。

所以ruby方法的参数,也都是引用类型。即使是基本的类型,比如布尔,整数,小数等,也是一样。

class MyObject
    attr_accessor :param1, :param2

    def show
        puts "param1 -> #{param1}", "param2 -> #{param2}"
    end
end

def modify_my_object!(obj)
    obj.param1 = 10
    obj.param2 = 20
end

new_obj = MyObject.new.tap {|x|
    x.param1 = 1
    x.param2 = 2
}
new_obj.show
# ->
# param1 -> 1
# param2 -> 2

modify_my_object!(new_obj)
new_obj.show
# ->
# param1 -> 10
# param2 -> 20

对于基本类型,传参的效果看起来向值类型,其实不是,只不过基本类型的对象是指向同一个,并且对象是无法修改的。

puts 1.object_id
puts 1.object_id
# ->
# 3
# 3

puts 1.111.object_id
puts 1.111.object_id
# ->
# -32029600549858966
# -32029600549858966

puts "string".object_id
puts "string".object_id
# -> 结果指向的 object_id 不一样
# 49335600 
# 49335540

puts true.object_id
puts true.object_id
# ->
# 20
# 20

puts nil.object_id
puts nil.object_id
# ->
# 8
# 8

每次的 String 都指向不同的 object_id,而 Fixnum、TrucClass、NilClass 则是指向相同的 object_id,他们是不可变的!

在方法内修改传进来的 Array,当然也包括上例的 MyObject,都是要小心的,为了避免对外部造成影响,可以这么做

def remove_first_element(arr)
    arr = arr.dup
    arr.delete_at(0)
    arr
end

array = [1, 2, 3, 4, 5]
array2 = remove_first_element(array)
p array, array2
# ->
# [1, 2, 3, 4, 5]
# [2, 3, 4, 5]

好了,关于引用的传参,就讲到这里吧~