Variables and Constants in Swift
In Swift, storing and managing data is one of the most fundamental concepts youβll use in every program. Swift provides two ways to store values: variables (which can change) and constants (which cannot change). Understanding when to use each one is crucial for writing safe, efficient Swift code.
π― What Youβll Learn
By the end of this lesson, youβll understand:
- The difference between variables (
var) and constants (let) - How to declare variables and constants
- Type inference and type annotations
- Swift naming conventions and best practices
- When to use variables vs constants
π¦ Constants with let
A constant is a value that you set once and cannot change later. In Swift, you declare constants using the let keyword.
Basic Syntax
let constantName = valueExample: Creating Constants
let pi = 3.14159let appName = "My Swift App"let maxUsers = 100let isEnabled = true
print(pi) // Output: 3.14159print(appName) // Output: My Swift AppConstants Cannot Be Changed
Once you assign a value to a constant, you cannot change it:
let userName = "Alice"userName = "Bob" // β Error: Cannot assign to value: 'userName' is a 'let' constantThis is actually a feature, not a limitation! It prevents accidental changes and makes your code safer.
Why Use Constants?
β
Safety - Prevents accidental value changes
β
Intent - Makes it clear the value shouldnβt change
β
Performance - Compiler can optimize better
β
Readability - Others know this value is fixed
[!TIP] Swift developers prefer
letby default. Useletwhenever possible, and only usevarwhen you know the value needs to change.
π Variables with var
A variable is a value that can change over time. You declare variables using the var keyword.
Basic Syntax
var variableName = valueExample: Creating Variables
var score = 0var playerName = "Player 1"var isGameOver = falsevar temperature = 25.5
print(score) // Output: 0Variables Can Be Changed
Unlike constants, you can modify variables after creating them:
var score = 0print("Initial score: \(score)") // Output: Initial score: 0
score = 10print("New score: \(score)") // Output: New score: 10
score = score + 5print("Updated score: \(score)") // Output: Updated score: 15Real-World Example: Counter
var pageViews = 0
// User visits pagepageViews = pageViews + 1print("Page views: \(pageViews)") // Output: Page views: 1
// Another visitpageViews = pageViews + 1print("Page views: \(pageViews)") // Output: Page views: 2
// Using shorthandpageViews += 1print("Page views: \(pageViews)") // Output: Page views: 3π var vs let: When to Use Which?
This is one of the most important decisions youβll make when writing Swift code.
Use let (Constants) When:
β
The value will never change
β
Youβre storing configuration values
β
Youβre storing mathematical constants
β
Youβre storing user input that wonβt be modified
β
When in doubt, start with let
Use var (Variables) When:
β
The value needs to change over time
β
Youβre building counters or accumulators
β
Youβre storing state that updates
β
Youβre working with user-modifiable data
Comparison Table
| Aspect | let (Constant) | var (Variable) |
|---|---|---|
| Can change value | β No | β Yes |
| Memory efficiency | Higher | Standard |
| Thread safety | Safer | Requires care |
| Compiler optimization | Better | Standard |
| Best practice | Use by default | Use when needed |
Example: Good Practices
// Good: Use let for values that don't changelet birthYear = 1990let companyName = "Apple Inc."let daysInWeek = 7
// Good: Use var for values that do changevar currentYear = 2024var age = currentYear - birthYear // This will be updatedvar userScore = 0 // Will increase during gameExample: Common Mistake
// β Bad: Using var when let would workvar pi = 3.14159 // This never changes, should be letvar appVersion = "1.0" // This doesn't change in runtime, should be let
// β
Good: Use let insteadlet pi = 3.14159let appVersion = "1.0"π·οΈ Type Inference
Swift is a statically typed language, meaning every variable and constant has a specific type. However, Swift can often figure out the type automatically - this is called type inference.
How Type Inference Works
When you assign a value, Swift infers the type:
let age = 25 // Swift infers: Intlet price = 19.99 // Swift infers: Doublelet name = "Alice" // Swift infers: Stringlet isActive = true // Swift infers: Boollet items = [1, 2, 3] // Swift infers: Array<Int>Type Inference Examples
// Integerlet score = 100// Swift knows: score is of type Int
// Double (decimal numbers)let temperature = 36.6// Swift knows: temperature is of type Double
// Stringlet greeting = "Hello"// Swift knows: greeting is of type String
// Booleanlet isLoggedIn = false// Swift knows: isLoggedIn is of type BoolBenefits of Type Inference
β
Less code to write - No need to specify types explicitly
β
Cleaner syntax - Code is more readable
β
Type safety - Still get all the benefits of static typing
β
Flexibility - Can still specify types when needed
π Type Annotations
Sometimes you want to explicitly specify the type of a variable or constant. This is done using type annotations.
Syntax
let constantName: Type = valuevar variableName: Type = valueWhen to Use Type Annotations
- When the type isnβt obvious
- When you want a specific number type
- When declaring without initial value
- For clarity and documentation
Example: Explicit Type Annotations
// Explicitly specify typeslet userName: String = "Alice"let userAge: Int = 25let accountBalance: Double = 1000.50let isPremium: Bool = false
// These are equivalent to:let userName = "Alice" // Swift infers Stringlet userAge = 25 // Swift infers Intlet accountBalance = 1000.50 // Swift infers Doublelet isPremium = false // Swift infers BoolExample: When Type Annotations Are Needed
1. Declaring Without Initial Value
// You must specify type if no initial valuevar username: Stringvar age: Intvar score: Double
// Later, assign valuesusername = "John"age = 30score = 95.52. Choosing Specific Number Types
// Without annotation, Swift chooses Int for whole numberslet count = 10 // Inferred as Int
// But you might want a different typelet count: UInt8 = 10 // Unsigned 8-bit integerlet count: Int64 = 10 // 64-bit integer3. Working with Floating-Point Numbers
// Swift defaults to Double for decimal numberslet price = 9.99 // Inferred as Double
// But you might want Floatlet price: Float = 9.99 // Explicitly Float (less precision, less memory)Example: Type Annotations for Clarity
// Without annotation - works but not clearlet radius = 5.0let area = 3.14159 * radius * radius
// With annotation - more clear and explicitlet radius: Double = 5.0let pi: Double = 3.14159let area: Double = pi * radius * radiusπ¨ Type Safety in Action
Swift wonβt let you mix types incorrectly:
var age = 25 // Intvar message = "Hello" // String
age = 30 // β
OK: Int to Intmessage = "Hi" // β
OK: String to String
age = "thirty" // β Error: Cannot assign String to Intmessage = 42 // β Error: Cannot assign Int to StringConverting Between Types
If you need to convert types, you must do it explicitly:
let ageString = "25"let ageInt = Int(ageString) // Convert String to Int
let score = 100let scoreDouble = Double(score) // Convert Int to Double
let pi = 3.14159let piInt = Int(pi) // Convert Double to Int (becomes 3)π Naming Conventions
Swift has specific conventions for naming variables and constants.
Rules (Must Follow)
- Start with letter or underscore - Cannot start with number
- Can contain letters, numbers, underscores - No spaces or special characters
- Case sensitive -
userNameandusernameare different - Cannot use Swift keywords - Unless wrapped in backticks
Conventions (Should Follow)
- Use camelCase - First word lowercase, subsequent words capitalized
- Be descriptive - Names should explain what they store
- Avoid abbreviations - Unless commonly known (URL, ID)
- Use singular for single values -
userNamenotuserNames - Use plural for collections -
itemsnotitemfor arrays
β Good Naming Examples
// Variables - camelCase, descriptivevar firstName = "John"var lastName = "Doe"var userAge = 25var isLoggedIn = falsevar accountBalance = 1500.50var itemCount = 10
// Constants - same naming as variableslet maxLoginAttempts = 3let apiEndpoint = "https://api.example.com"let defaultTimeout = 30β Bad Naming Examples
// Too short, not descriptivevar a = 25var x = "John"var b = true
// Using abbreviations unnecessarilyvar usrNm = "Alice"var acctBal = 1000
// Starting with number (won't compile)var 1stPlace = "Gold" // β Error
// Using spaces (won't compile)var user name = "Bob" // β ErrorSpecial Cases
// Using Swift keywords as names (not recommended)var `class` = "Math" // Backticks allow keywordsvar `let` = "constant" // But don't do this!
// Using underscores for unused valueslet _ = "ignored value" // Common in pattern matching
// Constants for math/physics (can use uppercase)let PI = 3.14159 // OK for well-known constantslet SPEED_OF_LIGHT = 299792458Boolean Naming
For boolean values, use is, has, should, or can prefixes:
var isActive = truevar hasPermission = falsevar shouldRefresh = truevar canEdit = falsevar didFinishLoading = trueπ Practical Examples
Letβs look at real-world examples combining what weβve learned.
Example 1: User Profile
// Constants - values that don't changelet userID = "12345"let email = "alice@example.com"let dateOfBirth = "1995-05-15"let accountType = "Premium"
// Variables - values that can changevar displayName = "Alice"var profilePicture = "default.jpg"var followerCount = 0var isOnline = false
// Updating variablesdisplayName = "Alice Smith"followerCount = 150isOnline = true
print("User: \(displayName)")print("Followers: \(followerCount)")print("Online: \(isOnline)")Output:
User: Alice SmithFollowers: 150Online: trueExample 2: Shopping Cart
// Product details (constants)let productName = "Laptop"let productPrice: Double = 999.99let taxRate: Double = 0.08
// Cart state (variables)var quantity = 1var subtotal = productPrice * Double(quantity)var tax = subtotal * taxRatevar total = subtotal + tax
print("Product: \(productName)")print("Quantity: \(quantity)")print("Subtotal: $\(subtotal)")print("Tax: $\(tax)")print("Total: $\(total)")
// User adds another itemquantity = 2subtotal = productPrice * Double(quantity)tax = subtotal * taxRatetotal = subtotal + tax
print("\nUpdated Cart:")print("Quantity: \(quantity)")print("Total: $\(total)")Output:
Product: LaptopQuantity: 1Subtotal: $999.99Tax: $79.9992Total: $1079.9892
Updated Cart:Quantity: 2Total: $2159.9784Example 3: Game Score System
// Game configuration (constants)let playerName = "Hero"let maxHealth = 100let startingLevel = 1
// Game state (variables)var currentHealth = maxHealthvar currentLevel = startingLevelvar score = 0var coinsCollected = 0
print("=== Game Started ===")print("Player: \(playerName)")print("Health: \(currentHealth)/\(maxHealth)")print("Level: \(currentLevel)")
// Player takes damagecurrentHealth -= 20print("\nπ₯ Took damage! Health: \(currentHealth)")
// Player collects coinscoinsCollected += 10score += 100print("π° Collected coins! Total: \(coinsCollected)")print("β Score: \(score)")
// Player levels upcurrentLevel += 1currentHealth = maxHealth // Health restoredprint("\nπ Level Up! Now level \(currentLevel)")print("Health restored to: \(currentHealth)")Output:
=== Game Started ===Player: HeroHealth: 100/100Level: 1
π₯ Took damage! Health: 80π° Collected coins! Total: 10β Score: 100
π Level Up! Now level 2Health restored to: 100ποΈ Practice Exercises
Exercise 1: Personal Information
Create constants and variables for personal information:
// Your solution here// Create constants for: name, birthYear// Create variables for: age, city, occupation// Print all valuesSolution:
// Constants (won't change)let name = "Sarah"let birthYear = 1995
// Variables (can change)var age = 29var city = "San Francisco"var occupation = "iOS Developer"
print("Name: \(name)")print("Birth Year: \(birthYear)")print("Age: \(age)")print("City: \(city)")print("Occupation: \(occupation)")
// Update variablesage = 30city = "Seattle"print("\nUpdated Info:")print("Age: \(age)")print("City: \(city)")Exercise 2: Temperature Converter
Create a converter that stores temperatures with proper use of constants and variables:
// Your solution here// Store a Celsius temperature as a constant// Calculate and store Fahrenheit as a variable// Use type annotationsSolution:
let celsius: Double = 25.0var fahrenheit: Double = (celsius * 9/5) + 32
print("\(celsius)Β°C is equal to \(fahrenheit)Β°F")
// Try another temperaturelet anotherCelsius: Double = 0.0fahrenheit = (anotherCelsius * 9/5) + 32print("\(anotherCelsius)Β°C is equal to \(fahrenheit)Β°F")Exercise 3: BMI Calculator
Calculate Body Mass Index using constants and variables:
// Your solution here// Create constants for: name, height (in meters), weight (in kg)// Calculate BMI as a variable// Formula: BMI = weight / (height * height)Solution:
let personName = "Alex"let heightInMeters: Double = 1.75let weightInKg: Double = 70.0
var bmi = weightInKg / (heightInMeters * heightInMeters)
print("Name: \(personName)")print("Height: \(heightInMeters)m")print("Weight: \(weightInKg)kg")print("BMI: \(bmi)")Output:
Name: AlexHeight: 1.75mWeight: 70.0kgBMI: 22.857142857142858π Common Mistakes and How to Avoid Them
Mistake 1: Using var When let Would Work
// β Badvar pi = 3.14159var appName = "MyApp"
// β
Goodlet pi = 3.14159let appName = "MyApp"Mistake 2: Trying to Change Constants
let score = 100score = 200 // β Error: Cannot assign to value: 'score' is a 'let' constant
// Solution: Use var if you need to change itvar score = 100score = 200 // β
OKMistake 3: Forgetting Type Annotations When Needed
// β Error: Type annotation missing in patternvar usernameusername = "Alice"
// β
Goodvar username: Stringusername = "Alice"
// Or even better: initialize immediatelyvar username = "Alice"Mistake 4: Mixing Types
var age = 25age = "twenty-five" // β Error: Cannot assign String to Int
// Solution: Keep types consistentvar age = 25age = 26 // β
OKπ‘ Key Takeaways
β
Use let for constants (values that donβt change)
β
Use var for variables (values that can change)
β
Prefer let by default - only use var when needed
β
Swift infers types automatically (type inference)
β
You can explicitly specify types (type annotations)
β
Use camelCase naming convention
β
Make names descriptive and meaningful
β
Swift is type-safe - canβt mix different types
π Next Steps
Now that you understand variables and constants, youβre ready to learn about:
Next lesson: Data Types in Swift
- Basic types: Int, Double, Float, Bool, String
- Type safety and type inference in depth
- Type conversion
- Working with tuples
π Quick Reference
// Constantslet constantName = valuelet name: Type = value
// Variablesvar variableName = valuevar name: Type = value
// Type annotationsvar age: Int = 25var price: Double = 19.99var name: String = "John"var isActive: Bool = true
// Type inferencelet age = 25 // Intlet price = 19.99 // Doublelet name = "John" // Stringlet isActive = true // BoolPractice makes perfect! Try creating your own examples with constants and variables. Experiment with different types and see what works. The more you practice, the more natural it will become! π―