Crash Courses · Basic
Variables, Constants, Types & Optionals
Master let/var, Swift's type system, numeric types, and the Optional type — Swift's solution to null safety.
14 min read+160 XP on completionCert: Swift Crash Course
Tap any word in the text below to start reading from there.
Variables, Constants, Types & Optionals
let and var
// let — constant (immutable). Use by default.
let maxScore = 100
let appName = "JST Academy"
// maxScore = 200 // ERROR: cannot assign to value: 'maxScore' is a 'let' constant
// var — variable (mutable). Use only when the value must change.
var currentScore = 0
currentScore += 10
currentScore += 25
print("Score: \(currentScore)") // Score: 35
// Type annotation when type cannot be inferred:
var message: String // no initial value — must annotate
message = "Hello"Rule: default to `let`. The compiler tells you when you need `var`.
---
Swift's Type Landscape
// Integer types
let i: Int = -42 // platform-native (64-bit on modern hardware)
let u: UInt = 42 // unsigned integer
let i8: Int8 = 127 // -128 to 127
let i16: Int16 = 32767
let i64: Int64 = 9_223_372_036_854_775_807
// Floating-point
let d: Double = 3.141592653589793 // 64-bit (default)
let f: Float = 3.14 // 32-bit
// Boolean
let isActive: Bool = true
// Character and String
let grade: Character = "A"
let name: String = "Jordan"
// Collection types
let numbers: [Int] = [1, 2, 3, 4, 5]
let scores: [String: Int] = ["Alice": 95, "Bob": 88]
let pair: (String, Int) = ("Age", 28) // tuple---
Optionals: The Null Safety System
In most languages, any variable can be null/nil. In Swift, only Optional types can be nil:
var name: String = "Jordan" // cannot be nil — compiler guarantees it
var alias: String? = nil // can be nil — the ? makes it Optional
// Optionals must be unwrapped before use:
print(name) // prints "Jordan" directly
// print(alias) // ERROR: value of optional type 'String?' must be unwrapped
// Safe way 1: if let (optional binding)
if let unwrapped = alias {
print("Alias: \(unwrapped)") // only runs if alias != nil
} else {
print("No alias set")
}
// Shorthand (Swift 5.7+) — same name:
if let alias {
print("Alias: \(alias)")
}
// Safe way 2: guard let (early exit)
func greet(_ name: String?) {
guard let name = name else {
print("No name provided")
return // exits the function
}
// name is a non-optional String here
print("Hello, \(name)!")
}
greet(nil) // No name provided
greet("Alice") // Hello, Alice!
// Safe way 3: nil coalescing (??)
let displayName = alias ?? "Anonymous"
print(displayName) // "Anonymous" since alias is nil
// Safe way 4: optional chaining (?.)
let upper = alias?.uppercased() // nil — safe, no crash
print(upper as Any) // nil
// UNSAFE: forced unwrap (!)
let forceAlias = alias! // CRASHES with fatal error if alias is nil---
Type Conversion
Swift never implicitly converts types. All conversions are explicit:
let i = 5
let d = 3.14
// let sum = i + d // ERROR: cannot add Int and Double directly
let sum = Double(i) + d // correct: convert i to Double first
print(sum) // 8.14
// String ↔ numeric conversions
let numStr = "42"
let parsed = Int(numStr) // Optional<Int> — might fail
let safeNum = Int(numStr) ?? 0 // safe: 42
let badParse = Int("abc") // nil
let num = 42
let asStr = String(num) // "42"
let asStr2 = "\(num)" // "42" — interpolation also works---
Tuples
Tuples group multiple values without a named type:
// Basic tuple
let point = (x: 3.0, y: 4.0)
print(point.x) // 3.0
print(point.y) // 4.0
// Destructuring
let (x, y) = (3.0, 4.0)
let (_, lat) = (longitude: -76.8, latitude: 17.99) // ignore first value
// Return multiple values from a function
func minMax(array: [Int]) -> (min: Int, max: Int) {
return (array.min()!, array.max()!)
}
let bounds = minMax(array: [3, 1, 7, 2, 9])
print("Min: \(bounds.min), Max: \(bounds.max)") // Min: 1, Max: 9---
Practical Optional Patterns
struct User {
let name: String
var email: String?
var phoneNumber: String?
}
func displayContact(_ user: User) {
print("Name: \(user.name)")
// Optional chaining + nil coalescing
let contact = user.email ?? user.phoneNumber ?? "No contact info"
print("Contact: \(contact)")
// Multiple optional bindings in one if let
if let email = user.email, let phone = user.phoneNumber {
print("Both: \(email), \(phone)")
} else if let email = user.email {
print("Email only: \(email)")
} else {
print("No email on file")
}
}
let jordan = User(name: "Jordan", email: "jordan@jst.com", phoneNumber: "876-555-0100")
let alice = User(name: "Alice", email: nil, phoneNumber: "876-555-0200")
displayContact(jordan)
displayContact(alice)Reading progress
0% read
In this module
Optional
if let
guard let
Optional Chaining
0%