在Ruby中将一个字符串设置为另一个字符串时的疯狂行为(至少对我而言)

Jin*_*Kim 0 ruby

作为一个新手,我可能错过了一些关于Ruby的东西,但对于我的生活,我不明白这个结果.所以我有这个简单的功能:

def crazyfunc(s)
  s.gsub!('a', 'b')
  #return has not purpose here
end
Run Code Online (Sandbox Code Playgroud)

现在我有这么简单的几套.

s1 = 'abc'
s2 = s1
s2 = crazyfunc(str2)

puts s1

=> bbc
Run Code Online (Sandbox Code Playgroud)

为什么世界上的s1受到crazyfunc的影响?所以这样做:

def crazyfunc(s)
  return s.gsub('a', 'b')
end
Run Code Online (Sandbox Code Playgroud)

不会改变str1,所以我认为它与inplace gsub正在做的事情有关.但我仍然没有得到为什么str1会被改变的逻辑.

Chr*_*ald 5

Ruby中的字符串赋值不会隐式复制字符串.您只是为它分配另一个引用.如果要复制字符串,请使用clone.

要演示,您可以检查对象ID:

ree-1.8.7-2010.02 > a = "foo"
 => "foo"
ree-1.8.7-2010.02 > b = a
 => "foo"
ree-1.8.7-2010.02 > a.object_id
 => 81728090
ree-1.8.7-2010.02 > b.object_id
 => 81728090
Run Code Online (Sandbox Code Playgroud)

由于ab具有相同的对象ID,你知道他们是同一个对象.如果要修改b为副本a,可以使用返回新字符串的方法(gsub而不是gsub!),或者可以使用b = a.clone,然后进行操作b.

ree-1.8.7-2010.02 > a = "foo"
 => "foo"
ree-1.8.7-2010.02 > b = a.clone
 => "foo"
ree-1.8.7-2010.02 > a.object_id
 => 81703030
ree-1.8.7-2010.02 > b.object_id
 => 81696040
ree-1.8.7-2010.02 > b.gsub! "f", "e"
 => "eoo"
ree-1.8.7-2010.02 > a
 => "foo"
ree-1.8.7-2010.02 > b
 => "eoo"
Run Code Online (Sandbox Code Playgroud)

或者更简单:

ree-1.8.7-2010.02 > a = "foo"
 => "foo"
ree-1.8.7-2010.02 > b = a.gsub("f", "e")
 => "eoo"
ree-1.8.7-2010.02 > puts a, b
foo
eoo
Run Code Online (Sandbox Code Playgroud)