Category: 02. Types & Functions

https://cdn3d.iconscout.com/3d/premium/thumb/function-3d-icon-png-download-11233846.png

  • Swift Closures

    Swift Closures

    Capture values and pass behavior as first-class functions using closure expressions and trailing closure syntax.


    Closure Expressions

    Closures are self-contained blocks of functionality that can be passed and stored.

    Syntax:

    • { (params) -> Return in statements }
    • shorthand args $0$1, and type inference.

    Example

    let nums = [3, 1, 2]
    let sorted = nums.sorted { $0 < $1 }
    let strings = sorted.map { "#\($0)" }
    print(strings) // ["#1", "#2", "#3"]

    This example sorts numbers using a closure with shorthand arguments and maps them to strings.


    Capturing Values

    Closures capture constants and variables from the surrounding context by reference.

    Syntax: func makeCounter() -> () -> Int { var n = 0; return { n += 1; return n } }

    Example

    func makeCounter() -> () -> Int {
      var n = 0
      return {
    
    n += 1
    return n
    } } let next = makeCounter() print(next()) // 1 print(next()) // 2

    The closure remembers n between calls, producing an incrementing counter.



    Trailing Closures

    If the last parameter is a closure, you can use trailing closure syntax for readability.

    Syntax: fn(x) { ... } instead of fn(x, closure: { ... })

    Example

    func repeatTimes(_ n: Int, _ work: () -> Void) {
      for _ in 0..<n { work() }
    }
    
    repeatTimes(3) {
      print("Hi")
    }
  • Swift Enums & Pattern Matching

    Enums & Pattern Matching

    Model finite sets of cases with enum, add associated values, and match using switch with patterns.


    Basic Enums

    Use enum to define a type with a fixed set of cases.

    Syntax: enum Direction { case north, south, east, west }

    Example

    enum Direction { case north, south, east, west }
    
    let d: Direction = .east
    print(d)

    This example defines an enum of directions and creates a value using a short dot syntax.


    Associated Values

    Attach data to each case using associated values.

    Syntax: enum Result { case success(T), failure(Error) }

    Example

    enum Barcode {
      case upc(Int, Int, Int, Int)
      case qr(String)
    }
    
    let b1 = Barcode.upc(8, 85909, 51226, 3)
    let b2 = Barcode.qr("HELLO")

    This example shows a barcode which may be a UPC with four integers or a QR code with a string.



    Pattern Matching

    Use switch with patterns to extract associated values.

    Syntax:

    • switch value { case .case(let x): ... }
    • if case for single-case checks

    Example

    func describe(_ code: Barcode) {
      switch code {
      case .upc(let numberSystem, let manufacturer, let product, let check):
    
    print("UPC: \(numberSystem)-\(manufacturer)-\(product)-\(check)")
    case .qr(let text):
    print("QR: \(text)")
    } } describe(b1) describe(b2)

    This example uses pattern matching to bind associated values and print a formatted description.


    Raw Values

    Provide default raw values (e.g., Int or String) and initialize from them.

    Syntax:

    • enum HTTPStatus: Int { case ok = 200, notFound = 404 }
    • HTTPStatus(rawValue: 200)

    Example

    enum HTTPStatus: Int { case ok = 200, notFound = 404 }
    
    let status = HTTPStatus(rawValue: 200)
    print(status == .ok)
  • Swift Optionals

    Swift Optionals

    Represent missing values safely with optionals, and unwrap them with ??if let, or guard let.


    What Are Optionals?

    An optional is a type that can hold either a value or nil (no value).

    Use ? to declare an optional, and nil-coalescing (??) or binding (if let) to safely read it.

    Syntax:

    • var x: String?
    • x ?? "default"
    • if let v = x { ... }
    • guard let v = x else { return }

    Example

    var nickname: String? = nil
    print(nickname ?? "(none)")
    
    nickname = "Ace"
    if let name = nickname {
      print(name)
    }

    This example prints a default using ?? and unwraps an optional safely with if let.

    Tip: Use guard let inside functions to early-exit on missing values.



    Guard Let

    Use guard let for early exit when required values are missing.

    Example

    func greet(_ input: String?) {
      guard let name = input else {
    
    print("Missing name")
    return
    } print("Hello, \(name)") } greet(nil) greet("Swift")
  • Swift Functions

    Swift Functions

    Define reusable code with parameters and return values; control labels, mutation with inout, defaults, and variadics.


    Defining and Calling Functions

    Use func to define a function with a name, parameters, and return value.

    Syntax:

    • func name(param: Type) -> Return
    • Call with name(param:)

    Example

    func greet(name: String) -> String {
      return "Hello, \(name)!"
    }
    print(greet(name: "Swift"))

    This example defines a function named greet that takes a String parameter and returns a greeting message.


    Parameters and Return Values

    Use func to define a function with multiple parameters and a return value.

    Syntax:

    • func name(param1: Type, param2: Type) -> Return
    • Multiple params: Separate by commas; annotate types.
    • Parameter labels: External names shown at call sites; use _ to omit.
    • Return type: Use ->; omit for Void.

    Example

    func add(_ a: Int, _ b: Int) -> Int { a + b }
    print(add(2, 3))

    This example omits external parameter labels with _ and returns the sum as an Int.



    Inout, Default Values, Variadics

    Use func to define a function with multiple parameters and a return value.

    Syntax:

    • func name(param: inout Type, default: Type = value)
    • func name(param: Type...)

    Example

    func increment(_ value: inout Int, by step: Int = 1) {
      value += step
    }
    var x = 10
    increment(&x)
    print(x) // 11
    
    func sum(_ nums: Int...) -> Int { nums.reduce(0, +) }
    print(sum(1,2,3))