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}, wherenis 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 constantStrings 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 lineString 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 accentBoth represent the same Character (é).
Counting Characters
Use the count property to get the number of characters:
let text = "Swift 🐦 Code"
print(text.count) // Prints 11Combining 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 4Accessing 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)]) // iInsert 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 StringSubstrings 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) // trueCheck 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:
utf8property (8-bit code units). - UTF-16:
utf16property (16-bit code units). - Unicode Scalars:
unicodeScalarsproperty (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