Variables & Data Types
Learn var vs let, type inference and annotations, Swift's basic types, string interpolation, tuples, and type safety.
On this page 14 sections
Introduction
Every Swift program is built out of values stored in variables and constants. Swift makes an unusually strong distinction between values that can change and values that can't — and pushes you toward the latter by default, which prevents a surprising number of bugs before they happen.
This lesson covers declaring variables and constants, letting Swift infer types automatically, Swift's basic data types, string interpolation, tuples, and why Swift never silently converts between types for you.
var vs let
Swift has two keywords for declaring storage: var for a variable whose value can change, and let for a constant whose value is set once and can never change afterward.
var score = 10 // variable — can changelet maxScore = 100 // constant — cannot change
score = 15 // OK// maxScore = 200 // Compile-time error: cannot assign to a constantThe Swift compiler will actually warn you if you declare something with var but never change it, nudging you toward let. This isn't just style — immutable values are easier to reason about and are automatically safe to share across concurrent code.
Type Inference
Swift is statically typed, but you rarely have to write types out by hand. The compiler infers a variable's type from its initial value at the point of declaration.
let city = "Bengaluru" // inferred as Stringlet temperature = 28.5 // inferred as Doublelet isRaining = false // inferred as BoolEven though you didn't write the types explicitly, they are fixed the moment the variable is created — city can never later be assigned an Int, for example.
Type Annotations
You can also state a type explicitly using a colon, which is useful when you want a specific type (like Double instead of the inferred Int) or when there's no initial value yet.
var age: Int = 25var price: Double = 19.99var name: String = "Priya"var isActive: Bool = truevar rating: Double // declared, no value yet — must be assigned before useBasic Types
Swift's standard library defines the core value types nearly every program uses.
| Type | Example | Notes |
|---|---|---|
| Int | 42, -7 | Whole numbers; 64-bit on modern platforms. |
| Double | 3.14, 0.001 | Double-precision floating point; the default for decimal literals. |
| Float | 3.14 | 32-bit floating point; less precise, rarely the default choice. |
| String | "Hello" | Unicode-correct text; a value type, not a reference type. |
| Character | "A" | A single extended grapheme cluster (one visible character). |
| Bool | true, false | Boolean logic value — no truthy/falsy numbers allowed. |
String Interpolation
Swift lets you embed the value of any expression directly inside a string literal using \(...), called string interpolation.
let user = "Aisha"let points = 42print("\(user) scored \(points) points")Click Run to see what this code prints.
Tuples
A tuple groups multiple values into one compound value, optionally with named elements. Tuples are useful for quickly bundling a few related values without defining a whole new type.
let httpResponse = (statusCode: 200, message: "OK")
print(httpResponse.statusCode)print(httpResponse.message)Click Run to see what this code prints.
Type Safety
Swift never silently converts between types, even numeric ones. Mixing an Int and a Double in an expression is a compile-time error unless you convert explicitly.
let wholeApples = 5let sharedAmong = 2
// let average = wholeApples / sharedAmong // Int division: 2, likely not what you wantlet average = Double(wholeApples) / Double(sharedAmong)print(average)Click Run to see what this code prints.
Dividing two Int values in Swift performs integer division and silently truncates the decimal portion, which is a very common source of subtle bugs — explicitly converting to Double first avoids it.
Type Aliases
A typealias gives an existing type a new, often more descriptive, name — purely for readability, it does not create a distinct type.
typealias Milliseconds = Int
func wait(for duration: Milliseconds) { print("Waiting for \(duration)ms")}wait(for: 500)Common Mistakes
- Reaching for
varout of habit even when a value never changes — preferletand let the compiler suggest otherwise. - Dividing two
Intvalues and being surprised the result truncates instead of producing a decimal. - Assuming Swift will implicitly convert an
Intto aDoublein a mixed expression — it never does; you must convert explicitly. - Forgetting a
Characterholds exactly one grapheme cluster, not an arbitrary-length string.
Best Practices
- Default to
let; only switch tovaronce you know a value genuinely needs to change. - Let type inference do the work for obvious literals, but add explicit annotations when the desired type isn't what would be inferred.
- Use tuples for small, temporary groupings of values; reach for a
structonce the data has real identity or behavior. - Convert numeric types explicitly and deliberately, rather than fighting the compiler with force casts.
Frequently Asked Questions
On modern 64-bit platforms (which is virtually all current Apple devices and desktops), Int is 64-bit. Swift also offers fixed-size types like Int32 and Int64 when you need to guarantee a specific width.
Double literals are the default for decimal numbers because Double offers roughly twice the precision of Float, and modern hardware handles both at similar speed, so there's little reason to default to the less precise option.
No — for value types like Int, String, and structs, a let constant is fully immutable. (Reference types declared with let can't be reassigned, but the object they point to could still change internally — covered in the structs & classes lesson.)
Key Takeaways
- Use
letfor constants andvarfor variables — Swift nudges you towardletby default. - Type inference fills in types automatically from initial values; type annotations state them explicitly.
- Core basic types are Int, Double, Float, String, Character, and Bool.
- String interpolation with
\(...)embeds any expression's value inside a string. - Swift never implicitly converts between numeric types — conversions must be explicit.
Summary
You now know how to declare variables and constants, let Swift infer types or state them explicitly, and work with the language's core data types safely. Next, you'll learn how to control the flow of your programs with conditionals, switch statements, and loops.