LearnAI ToolsCareerPractice BuildsPlayDevelopmentContact
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.

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