LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 416 min read

Variables & Data Types

Learn var vs let, type inference and annotations, Swift's basic types, string interpolation, tuples, and type safety.

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 change
let maxScore = 100 // constant — cannot change
score = 15 // OK
// maxScore = 200 // Compile-time error: cannot assign to a constant

The 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 String
let temperature = 28.5 // inferred as Double
let isRaining = false // inferred as Bool

Even 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 = 25
var price: Double = 19.99
var name: String = "Priya"
var isActive: Bool = true
var rating: Double // declared, no value yet — must be assigned before use

Basic Types

Swift's standard library defines the core value types nearly every program uses.

TypeExampleNotes
Int42, -7Whole numbers; 64-bit on modern platforms.
Double3.14, 0.001Double-precision floating point; the default for decimal literals.
Float3.1432-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).
Booltrue, falseBoolean 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 = 42
print("\(user) scored \(points) points")
Output

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)
Output

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 = 5
let sharedAmong = 2
// let average = wholeApples / sharedAmong // Int division: 2, likely not what you want
let average = Double(wholeApples) / Double(sharedAmong)
print(average)
Output

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

Avoid These Mistakes
  • Reaching for `var` out of habit even when a value never changes — prefer `let` and let the compiler suggest otherwise.
  • Dividing two `Int` values and being surprised the result truncates instead of producing a decimal.
  • Assuming Swift will implicitly convert an `Int` to a `Double` in a mixed expression — it never does; you must convert explicitly.
  • Forgetting a `Character` holds exactly one grapheme cluster, not an arbitrary-length string.

Best Practices

  • Default to `let`; only switch to `var` once 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 `struct` once 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 `let` for constants and `var` for variables — Swift nudges you toward `let` by 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.

Next Lesson →

Control Flow