object_id在Ruby中通常用于判断两个对象是不是一个物理上的东西.
object_id相同的对象可以理解为它们都指向了同一个值.
例如,String类的对象 :
执行结果 :
例如, Array类的对象也一样 :
执行结果 :
s1 = %Q/Hello, I'm Digoal.Zhou/
s2 = s1 # 把一个String对象赋值给另一个对象, 其实是一次reference赋值
s3 = s1.clone() # 使用clone()方法则不是reference操作, 而是重新创建了一个对象.
puts(s1.class)
puts(s2.class)
puts("s1: #{s1}")
puts("s2: #{s2}")
puts(s1.object_id) # 看看这三个对象的object_id就知道了.
puts(s2.object_id)
puts(s3.object_id)
s1.reverse!
puts("s1: #{s1}") # 修改s1 后 , s2其实也修改了, 因为它们执行同一个值.
puts("s2: #{s2}")
puts("s3: #{s3}") # 显然s3是另一个对象, 修改s1,s2对它没反映.
s2.capitalize!
puts("s1: #{s1}")
puts("s2: #{s2}")
puts("s3: #{s3}")
s1.reverse! << '. What\'s your name?'
puts("s1: #{s1}")
puts("s2: #{s2}")
puts("s3: #{s3}")
s2[0,6] = 'DIG' # 这是修改从0号index开始的6个字符.即"hello,"改为"DIG"
puts("s1: #{s1}")
puts("s2: #{s2}")
puts("s3: #{s3}")
puts(s1.object_id)
puts(s2.object_id)
puts(s3.object_id)
执行结果 :
String
String
s1: Hello, I'm Digoal.Zhou
s2: Hello, I'm Digoal.Zhou
16581468
16581468
16581456
s1: uohZ.laogiD m'I ,olleH
s2: uohZ.laogiD m'I ,olleH
s3: Hello, I'm Digoal.Zhou
s1: Uohz.laogid m'i ,olleh
s2: Uohz.laogid m'i ,olleh
s3: Hello, I'm Digoal.Zhou
s1: hello, i'm digoal.zhoU. What's your name?
s2: hello, i'm digoal.zhoU. What's your name?
s3: Hello, I'm Digoal.Zhou
s1: DIG i'm digoal.zhoU. What's your name?
s2: DIG i'm digoal.zhoU. What's your name?
s3: Hello, I'm Digoal.Zhou
16581468
16581468
16581456
例如, Array类的对象也一样 :
a1 = Array.new([1,2,3,4,5])
a2 = a1
a3 = a1.clone()
print("a1,#{a1}\n")
print("a2,#{a2}\n")
print("a3,#{a3}\n")
puts(a1.object_id)
puts(a2.object_id)
puts(a3.object_id)
a1[0] = "DIGOAL"
print("a1,#{a1}\n")
print("a2,#{a2}\n")
print("a3,#{a3}\n")
puts(a1.object_id)
puts(a2.object_id)
puts(a3.object_id)
执行结果 :
a1,[1, 2, 3, 4, 5]
a2,[1, 2, 3, 4, 5]
a3,[1, 2, 3, 4, 5]
15533280
15533280
15533256
a1,["DIGOAL", 2, 3, 4, 5]
a2,["DIGOAL", 2, 3, 4, 5]
a3,[1, 2, 3, 4, 5]
15533280
15533280
15533256
但是需要注意的是, 如果前面例子中的s1不是通过!方法或<<连接的,(也就是不修改s1本身) . 而是通过赋值一个字符串(哪怕相同的字符串)或其他对象的话.
s1 的object_id将改变, 也就是说指向另一个值了, 但是s2还是指向原来的值. 我们来看个例子 :
执行结果 :
但是对于Fixnum类的对象, 和Array,String类不太一样, 只要值相同, object_id就相同.
执行结果 :
注意仅限于Fixnum, 新赋予的Float值相同, object_id也不同 .
执行结果 :
s1 = "Hello, I'm Digoal. What's your name?"
s2 = s1
puts(s1.object_id)
puts(s2.object_id)
s1 = "Hello, I'm Digoal. What's your name?" # 虽然这里赋予了相同的值, 但是实际上是新产生了一个对象ID.
puts(s1.object_id)
puts(s2.object_id)
s1 << " Let's go." # 所以对s1改变时, s2不会受到影响. 因为它们指向的不是一个值了.
puts(s1)
puts(s2)
执行结果 :
16121508
16121508
16121412
16121508
Hello, I'm Digoal. What's your name? Let's go.
Hello, I'm Digoal. What's your name?
但是对于Fixnum类的对象, 和Array,String类不太一样, 只要值相同, object_id就相同.
f1 = 10
f2 = f1
puts(f1.class)
puts(f2.class)
puts(f1.object_id)
puts(f2.object_id)
f1 = 10
puts(f1.object_id)
puts(f2.object_id)
执行结果 :
Fixnum
Fixnum
21
21
21
21
注意仅限于Fixnum, 新赋予的Float值相同, object_id也不同 .
f1 = 10.0
f2 = f1
puts(f1.class)
puts(f2.class)
puts(f1.object_id)
puts(f2.object_id)
f1 = 10.0
puts(f1.object_id)
puts(f2.object_id)
执行结果 :
Float
Float
16354536
16354536
16354128
16354536