As far as I can tell, there are currently two ways to fetch a String from an AttributedString at the moment, both revolving around AttributedString.CharacterView:
-
Stringhas an initializer which takes aSequenceofCharactersand constructs itself from that sequence. Given anAttributedStringattrStr, you can writeString(attrStr.characters).However: I believe there's may be a performance pitfall here, because as far as I can tell, there's currently no fast-path in place here to help avoid iterating over
charactersone character at a time with a regularfor-inloop, which is slower than getting to copy bytes from an underlying buffer directly -
It's not particularly intuitive to find, but the
AttributedStringwork added an initializer toStringwhich takes a slice of anAttributedString, reaches into its_gutsto grab the underlyingString, slices the underlyingString, and returns a bulk copy of that.Although also necessarily an O(n) copy, ths should be faster in practice than iterating over the character view and copying one character at a time.
You can achieve this at the moment by writing
String(attrStr.characters[...]).
I haven't thought through the slicing aspects, but it appears to me that not offering read access to the underlying String directly may only be an API oversight. Someone from the Foundation team, feel free to correct me, but this may be worth filing Feedback for. (As an alternative, it also seems reasonable to offer String.init(_: AttributedString.CharacterView) and String.init<S: AttributedStringProtocol>(_: S) as fast-path shortcuts for performing this conversion with fewer performance implications.)