The following code creates a string and then a substring from that string:
let x = "a quick brown fox jumped over the lazy dog"
let range = x.startIndex...x.index(x.startIndex, offsetBy: 6)
var substring = x[range]
From what I understand, substring
should share its memory with the string x
. But if I do:
substring.replaceSubrange(substring.startIndex...substring.startIndex, with: "t")
print(substring)
print(x)
I get the following output:
t quick
a quick brown fox jumped over the lazy dog
Which means that they don't share the same memory anymore.
So, how does the memory sharing thing work? Does the call to replaceSubrange
make a defensive copy of the text "a quick" inside the substring
object and then replace the first letter "a" with "t"?
Or is " quick" still shared with the original string x
, but the new memory was allocated only for the first character "t"? As far as I know that shouldn't be possible, because arrays store their memory continuously.
So, at which point did substring
stop sharing its memory with x
?
CodePudding user response:
According to Apple's docs, Substring
instance is the result of slice of a string. It shares its storage with the original string which it is store inside this SubString
not the original.
First, you need to know just like your example x
is a String which is a value not a class. So it shares its memory with this x
will and never happend.
When you create a Substring
it automatically copy the value of your x
which is a quick brown fox jumped over the lazy dog
into a type Slice<String>
as base
and return back to you a Substring
which is String.SubSequence
of this own Slice<String>
. And this base
share its storage with Substring
and no connection with the original x
Because of that, when ever you change the value x
not making the value of this Slice<String>
change too.
Example like this
var x = "a quick brown fox jumped over the lazy dog" // your original string
let range = x.startIndex...x.index(x.startIndex, offsetBy: 6)
var substring = x[range] // copy your original and combine with start index and end index
print("first substring: ", substring) // your desire result
print("base of substring: ", substring.base) // the value of x when clone into when creating substring
x = "abcder" // changing value x
print("second substring: ", substring) // still the same
print("base of substring: ", substring.base) // still the same