Strings and Characters
Swift's String
and Character
types provide a robust, Unicode-compliant way to work with text. Strings are represented by the String
type, which is a collection of Character
values. This document covers the essentials of creating, manipulating, and accessing strings in Swift, with simplified examples.
String Literals
A string literal is a sequence of characters enclosed in double quotation marks ("
).
let greeting = "Hello, Swift!"
Swift infers the String
type for greeting
because it’s initialized with a string literal.
Multiline String Literals
For strings spanning multiple lines, use a multiline string literal with three double quotation marks ("""
):
let multiLine = """
Welcome to Swift programming.
This is a multiline string.
It spans several lines.
"""
The string starts on the first line after the opening """
and ends on the line before the closing """
, excluding line breaks at the start or end unless explicitly included.
To include line breaks in the source code without affecting the string’s value, use a backslash (\
) at the end of a line:
let noLineBreaks = """
Line one ends here. \
Line two continues without a break.
"""
To include a line break at the start or end, add a blank line:
let withLineBreaks = """
This starts with a line break.
It ends with one too.
"""
Indentation in multiline strings is handled by matching the whitespace before the closing """
. Extra indentation beyond this is included in the string.
Special Characters in String Literals
String literals support special characters:
- Escaped characters:
\0
(null),\\
(backslash),\t
(tab),\n
(line feed),\r
(carriage return),\"
(double quote),\'
(single quote). - Unicode scalars:
\u{n}
, wheren
is a 1–8 digit hexadecimal number.
Examples:
let quote = "\"Swift is fun!\" - Developer"
let currency = "\u{24}" // $
let heart = "\u{2665}" // ♥
let star = "\u{1F31F}" // 🌟
In multiline strings, include a double quote ("
) without escaping, but escape at least one quote to include """
:
let multiQuotes = """
A single quote: "
All three quotes: \"\"\"
"""
Extended String Delimiters
Use extended delimiters (#
) to include special characters without their effect:
let rawString = #"No newline: \n"#
For interpolation within extended delimiters, match the number of #
symbols:
let calc = #"Result: \#(2 + 3)"# // Prints "Result: 5"
Initializing an Empty String
Create an empty string using an empty literal or initializer:
var empty = ""
var anotherEmpty = String()
Check if a string is empty with the isEmpty
property:
if empty.isEmpty {
print("String is empty")
}
String Mutability
Strings are mutable when assigned to a variable (var
) and immutable when assigned to a constant (let
):
var mutable = "Swift"
mutable += " Programming"
// mutable is now "Swift Programming"
let constant = "Code"
// constant += " More" // Error: cannot modify a constant
Strings as Value Types
Swift’s String
is a value type, meaning it’s copied when assigned or passed to a function. The compiler optimizes copying to occur only when necessary, ensuring good performance.
Working with Characters
Iterate over a string’s characters with a for
-in
loop:
for char in "Swift!" {
print(char)
}
// Prints:
// S
// w
// i
// f
// t
// !
Create a Character
from a single-character string literal:
let star: Character = "*"
Construct a string from an array of characters:
let chars: [Character] = ["S", "w", "i", "f", "t"]
let swiftString = String(chars) // "Swift"
Concatenating Strings and Characters
Concatenate strings with the +
operator or append with +=
:
let part1 = "Hello"
let part2 = " World"
var combined = part1 + part2 // "Hello World"
combined += "!" // "Hello World!"
Append a character with the append(_:)
method:
combined.append("*") // "Hello World!*"
Ensure multiline strings end with a line break for consistent concatenation:
let start = """
First line
Second line
"""
let end = """
Third line
"""
print(start + end)
// Prints:
// First line
// Second line
// Third line
String Interpolation
Insert values into a string using \(expression)
:
let number = 5
let text = "\(number) doubled is \(number * 2)"
// text is "5 doubled is 10"
With extended delimiters, match the number of #
symbols for interpolation:
print(#"Value: \#(number * 2)"#) // Prints "Value: 10"
Unicode
Swift’s String
and Character
types are Unicode-compliant. A Character
represents an extended grapheme cluster, combining one or more Unicode scalars into a single human-readable character.
Examples:
let eAcute: Character = "\u{E9}" // é
let combinedEAcute: Character = "\u{65}\u{301}" // e + combining acute accent
Both represent the same Character
(é
).
Counting Characters
Use the count
property to get the number of characters:
let text = "Swift 🐦 Code"
print(text.count) // Prints 11
Combining scalars (e.g., e
+ U+0301
) doesn’t increase the character count:
var word = "code"
word += "\u{301}" // Adds combining acute accent
print(word.count) // Still 4
Accessing and Modifying Strings
Use String.Index
to access characters, as Swift strings can’t use integer indices due to variable memory requirements for Unicode characters.
Access characters:
let text = "Swift Code"
print(text[text.startIndex]) // S
print(text[text.index(before: text.endIndex)]) // e
print(text[text.index(text.startIndex, offsetBy: 2)]) // i
Insert characters or strings:
var text = "Swift"
text.insert("!", at: text.endIndex) // "Swift!"
text.insert(contentsOf: " is", at: text.index(before: text.endIndex)) // "Swift is!"
Remove characters or substrings:
text.remove(at: text.index(before: text.endIndex)) // "Swift is"
let range = text.index(text.endIndex, offsetBy: -3)..<text.endIndex
text.removeSubrange(range) // "Swift"
Substrings
Substrings, obtained via methods like prefix(_:)
or subscripts, are of type Substring
. Convert to String
for long-term storage:
let greeting = "Hello, Swift!"
let index = greeting.firstIndex(of: ",") ?? greeting.endIndex
let substring = greeting[..<index] // "Hello"
let newString = String(substring) // Convert to String
Substrings reuse the original string’s memory, optimizing performance but requiring conversion for persistence.
Comparing Strings
Compare strings with ==
and !=
for canonical equivalence:
let text1 = "café"
let text2 = "caf\u{65}\u{301}"
print(text1 == text2) // true
Check prefixes and suffixes with hasPrefix(_:)
and hasSuffix(_:)
:
let scenes = [
"Scene 1: Park",
"Scene 2: Cafe",
"Scene 3: Park View"
]
var parkCount = 0
for scene in scenes {
if scene.hasPrefix("Scene ") {
parkCount += 1
}
}
print("Scenes: \(parkCount)") // Prints "Scenes: 3"
Unicode Representations
Access Unicode representations of a string:
- UTF-8:
utf8
property (8-bit code units). - UTF-16:
utf16
property (16-bit code units). - Unicode Scalars:
unicodeScalars
property (21-bit values).
Example:
let text = "Swift🌟"
for code in text.utf8 {
print("\(code) ", terminator: "")
}
// Prints: 83 119 105 102 116 240 159 140 159