If you replace a sliced String.SubSequence value with a completely different text that doesn't match any portion of the original String, how is it going to share its storage with that String?

let playground: String = "Hello, playground"

let start: String.Index = playground.startIndex
let end: String.Index = playground.index(start, offsetBy: 4)
let range: ClosedRange<String.Index> = start...end

var firstFive: String.SubSequence = playground[range]

Page 75, text extracted from below Figure 7.2:

You will find that firstFive is what is called a “slice” of the original String contained by the playground constant. A slice represents some subcomponent of the original sequence.

Since firstFive is a slice of playground, it is a substring carved out of the original “Hello, playground” String. Slicing a substring from an existing String does not create a new instance of that type. This is efficient, because it means that firstFive does not need its own storage. It shares its storage with playground.

Here I made some assumptions that made me a little bit confused.

Since firstFive is an exact subcomponent of the original sequence playground then in this particular example I’m assuming that both these variables must be two references that point to the same instance, is that right? However, if I modify firstFive by changing its text:

firstFive = "Greetings, Big Nerd Ranch Forums!🤠"

firstFive is now a completely different sequence, it’s no longer an exact subcomponent of playground so my assumption of two references pointing at the same instance doesn’t make sense to me here. At this point, how is firstFive sharing its storage with playground? And why firstFive is still declared as String.SubSequence if you option-click it, shouldn’t it be stored as a new String instance?


Only partially answering the questions. You are seeing the copy-on-write at work here, a technique used by Swift to optimise storage of objects.

I don’t have the book, but they should talk about the copy-on-write following the quoted text.

1 Like

Substrings aren’t really meant to be used like that. They’re mainly intended for cases where you need to temporarily use a subsection of an existing string as-is and don’t want to bother making a copy of it. If you wanted to copy a section of a string & then change it, you would make a new String.

You should read the “Substrings” section of the Swift documentation on Strings.

1 Like

copy-on-write isn’t mentioned following the quoted text however at the end of the following chapter 8 (Arrays) they introduce you to the Swift documentation and advice you to explore its “Array” section. There, I found an explanation of it:

Arrays, like all variable-size collections in the standard library, use copy-on-write optimization. Multiple copies of an array share the same storage until you modify one of the copies. When that happens, the array being modified replaces its storage with a uniquely owned copy of itself, which is then modified in place. Optimizations are sometimes applied that can reduce the amount of copying.

This means that if an array is sharing storage with other copies, the first mutating operation on that array incurs the cost of copying the array. An array that is the sole owner of its storage can perform mutating operations in place.