In This Article
In the previous chapter, you worked with integers and doubles. But Swift has a rich type system that goes far beyond numbers. In this chapter, you'll learn how types interact with each other, how Swift can infer types for you, and how to work with text using strings. You'll also discover tuples — a simple way to group related values together.
Type Conversion: Being Explicit
Swift is strict about types. You can't accidentally mix them. Consider this:
Many languages would silently convert this for you. Swift refuses. Why? Because silent conversions are a major source of bugs. When you convert a Double to an Int, you lose the decimal part. Swift wants you to acknowledge that loss explicitly:
By wrapping the value in Int(), you're telling Swift: "Yes, I know I'm losing precision. Do it anyway." This explicitness prevents an entire category of subtle bugs.
Working With Mixed Types
The same strictness applies to operations. You can't multiply an Int by a Double directly:
Swift makes you choose: should the result be a Double (preserving the decimal) or an Int (rounding down)? Almost always, you want to preserve precision:
Convert the less precise type to the more precise one. Converting the Int to a Double loses nothing. Going the other way would round 19.5 down to 19.
Type Inference: Let Swift Figure It Out
You've been writing type annotations on every declaration. But Swift's compiler is smart enough to figure out types on its own:
This is called type inference. Swift looks at the value you're assigning and determines the type automatically. The result is identical to writing the type explicitly — it's just less typing.
In a playground, hold Option and click on any variable or constant name. Xcode will show you a popover with the inferred type. This is invaluable when you're not sure what type Swift chose.
Sometimes you want a specific type that differs from what Swift would infer. There are three ways to handle this:
Strings: Working With Text
Numbers are just the beginning. Most apps deal heavily with text — names, messages, labels, URLs. In Swift, text is represented by the String type.
How computers store text
At the hardware level, computers only understand numbers. So every character maps to a number via a standard called Unicode. The letter "a" is 97, "b" is 98, and so on. Unicode covers every writing system on Earth — Latin, Chinese, Arabic, Cyrillic — plus emoji. The character "🐶" is code point 128054.
You don't need to think about code points in daily programming. Swift handles all the encoding automatically. But knowing it's all numbers underneath helps you understand why strings behave the way they do.
Characters and Strings
Character holds exactly one character. String holds zero or more. Swift always infers string literals as String, so you need an explicit type annotation if you want a Character.
Combining strings
You can join strings together using the + operator, just like adding numbers:
Notice that adding a Character to a String requires explicit conversion — the same type strictness you saw with numbers.
String Interpolation
Concatenation works, but there's a better way to build strings with dynamic values. String interpolation lets you embed values directly inside a string:
Use \(expression) inside a string literal to insert any value. This works with all types — strings, numbers, booleans, even expressions:
String interpolation is one of Swift's most-used features. It's cleaner than concatenation and handles type conversion automatically.
Multi-line Strings
For longer text, Swift supports multi-line string literals using triple quotes:
The indentation of the closing """ determines the baseline. Swift strips that many leading spaces from every line, so your code can be nicely indented without affecting the output. The first and last newlines (right after and before the triple quotes) are not included in the string.
Tuples: Grouping Related Values
Sometimes you need to group a few values together without creating a full type. That's what tuples are for. They're lightweight containers for related data:
Access values by position (starting from 0):
Named tuples
Position-based access is unclear. Named tuples are much better:
Decomposing tuples
You can extract multiple values at once:
The underscore (_) is Swift's "I don't care about this value" operator. You'll see it throughout the language.
Tuples are great for returning multiple values from a function or grouping temporary data. For anything more complex or reusable, you'll want a struct (covered in a later chapter). Think of tuples as quick, disposable groupings.
The Full Range of Number Types
You've been using Int and Double. Swift actually has many more numeric types, each with different storage sizes and ranges:
Signed integers (can be negative): Int8, Int16, Int32, Int64
Unsigned integers (zero and positive only): UInt8, UInt16, UInt32, UInt64
Decimals: Float (4 bytes, ~6 digits precision) and Double (8 bytes, ~15 digits precision)
Int is 64-bit on modern hardware. Double is the default for decimals. Use these two 99% of the time. The specific-size types exist for interoperability with other systems or when optimizing memory.
When mixing specific number types, convert to a common type:
Type Aliases
You can create custom names for existing types using typealias. This doesn't create a new type — it's just a more readable name:
Type aliases shine when working with complex types. They make your code self-documenting without adding overhead.
A Peek at Protocols
You might wonder: with so many number types, how does Swift keep them manageable? The answer is protocols — one of Swift's most powerful features.
A protocol defines a set of operations that a type must support. All integer types conform to the BinaryInteger protocol, which itself conforms to Numeric. This means once you know how to use one integer type, you know how to use them all — they share the same operations.
You'll dive deep into protocols later in this series. For now, just know that Swift organizes types by their shared behaviors, and this is what makes the type system feel consistent rather than overwhelming.
Exercises
Try These in Your Playground
- Create constants
age1 = 42andage2 = 21. Calculate their average using(age1 + age2) / 2. What's wrong with the result? Fix it usingDoubleconversion. - Create a
firstNameandlastNameconstant. Build afullNamestring using concatenation, then build anintroductionusing string interpolation. - Create a named tuple representing today's date with
month,day,year, andavgTemperature. Extract just thedayandavgTemperatureinto constants using decomposition (ignore the rest with_). - What is the value of
"\(10) multiplied by \(5) equals \(10 * 5)"? - Given
let a = 4,let b: Int32 = 100,let c: UInt8 = 12— what isInt(a) + Int(b) - Int(c)? - Bonus: What is the numeric difference between
Double.piandFloat.pi? Try it in a playground.
Key Points
What You Learned
- Swift requires explicit type conversion — no silent, automatic casting
- Convert to the more precise type when mixing
IntandDouble - Type inference lets you omit type annotations when Swift can figure it out
- Unicode maps every character (including emoji) to a number called a code point
Stringstores text;Characterstores a single character- Concatenate strings with
+or build them with interpolation:\(value) - Triple-quoted strings (
""") support multi-line text - Tuples group related values of any type:
(x: 2, y: 3) - Decompose tuples into individual constants; use
_to ignore values - Swift has many numeric types (
Int8throughInt64,UInt8throughUInt64,Float,Double) but you'll mostly useIntandDouble typealiascreates readable names for existing types- Protocols define shared behavior across types — a core concept you'll explore later
In the next chapter, we'll cover Control Flow — how to make decisions with if/else, pattern match with switch, and repeat work with loops.
See these concepts in action
Our Swift Fundamentals video course covers variables, types, strings, and more with 96 video lessons.
Watch Swift Videos