为什么字符串中的字符没有变异?

Srd*_*No1 2 ruby string

def test_problem(str)
  str[3].upcase! # str[3] = str[3].upcase! works
  str
end

p test_problem("hello")
Run Code Online (Sandbox Code Playgroud)

我的问题是为什么String.upcase!哪个是mutating方法不会在上面的情况下改变字符串,但你需要在字符串中重新分配该字符?

max*_*ner 6

String#[]返回一个新字符串,如文档所示.

a = "foo"
a.object_id
# => 70217975553640

a[0].object_id
# => 70217957574840
Run Code Online (Sandbox Code Playgroud)

字符串不是由字符对象组成的,它是一个单独的对象(至少在表面上,我不确定C内部).所以没有办法提取一个字符并仍然属于原始字符串 - 如果你想改变字符串,你需要整个字符串.

String#[]= 另一方面确实改变了字符串

你可以这样做你的方法:

def test_problem(str)
  str[3] = str[3].upcase # dont use bang methods when assigning
  str
end
Run Code Online (Sandbox Code Playgroud)