String is currently serving as its own subsequence, allowing substrings to share storage with their "owner". This can lead to memory leaks when small substrings of larger strings are stored long-term (see here for more detail on this problem). Introducing a separate type of
Substring to serve as
String.Subsequence is recommended to resolve this issue, in a similar fashion to
A new type,
Substring , will be introduced. Similar to
ArraySlice it will be documented as only for short- to medium-term storage:
Long-term storage of
Substring instances is discouraged. A substring holds a reference to the entire storage of a larger string, not just to the portion it presents, even after the original string’s lifetime ends. Long-term storage of a substring may therefore prolong the lifetime of elements that are no longer otherwise accessible, which can appear to be memory leakage.
Aside from minor differences, such as having a
Self and a larger size to describe the range of the subsequence,
Substring will be near-identical from a user perspective.
The introduction of
Substring came about from practical experience of code holding on to
Strings permanently, when those
Strings were really slices of much larger data, effectively wasting memory.
But it's possible that it is a type because a type is the only marking system that Swift offers to assert that the
Substring has been minimized
Yep, this is it. The API between
Substring is meant to be as close to identical as possible (so much so that most operations on
String-like objects should likely be using
StringProtocol itself, which abstracts over the two), but the type of
String indicates to you that it is the owner of its entire buffer, whereas
Substring is not (i.e., direct storage of
Substrings should be a code smell that indicates that you really want conversion to
String to "minimize" the slice).
The full rationale behind this perhaps isn't spelled out as clearly as it could be in the
Substring docs, but it does at least say
Don’t store substrings longer than you need them to perform a specific operation. A substring holds a reference to the entire storage of the string it comes from, not just to the portion it presents, even when there is no other reference to the original string. Storing substrings may, therefore, prolong the lifetime of string data that is no longer otherwise accessible, which can appear to be memory leakage.