“\r\n” is one Character in Swift

From the department of “how did I not realise this sooner?!”:

  1> "\r".count
$R0: Int = 1
  2> "\n".count 
$R1: Int = 1
  3> "\r\n".count 
$R2: Int = 1

Yes, Swift treats the two bytes “\r\n” as a single character.  This is actually super convenient a lot of the time, because it means algorithms that look for line breaks with isNewline just work, even on “Windows”-style text.  Otherwise, you’d have to explicitly look for two isNewline characters in sequence and check if they are exactly “\r\n”.

But it does lead to some potentially surprising side-effects, like:

 4> x.unicodeScalars.count
$R3: Int = 2
 5> Array(x.unicodeScalars)
$R4: [String.UnicodeScalarView.Element] = 2 values {
  [0] = U'\r'
  [1] = U'\n'
}

This isn’t surprising if you’re pretty familiar with how Unicode actually works – starting with the difference between graphemes (approximately what Swift calls a Character) and “scalars”, but I suspect it’ll catch some people out.

Leave a Comment