乐闻世界logo
搜索文章和话题

What are the differences between structs and classes in Swift? When to choose structs?

2月21日 15:05

What are the differences between structs and classes in Swift? In what situations should you choose structs over classes?

Structs and classes in Swift are both constructs for defining custom data types, but they have important differences in memory management, assignment behavior, and use cases.

Main Differences:

  1. Value Type vs Reference Type:

    • Structs are value types, creating copies when assigned
    • Classes are reference types, passing references when assigned
    • Example:
      swift
      struct Point { var x: Int var y: Int } class Circle { var center: Point var radius: Int init(center: Point, radius: Int) { self.center = center self.radius = radius } } var point1 = Point(x: 0, y: 0) var point2 = point1 point2.x = 10 print(point1.x) // 0 (point1 is not affected) var circle1 = Circle(center: Point(x: 0, y: 0), radius: 5) var circle2 = circle1 circle2.radius = 10 print(circle1.radius) // 10 (circle1 is affected)
  2. Inheritance:

    • Classes support inheritance, can inherit properties and methods from other classes
    • Structs do not support inheritance
    • Example:
      swift
      class Vehicle { var speed: Int = 0 func accelerate() { speed += 10 } } class Car: Vehicle { var brand: String init(brand: String) { self.brand = brand } }
  3. Type Casting:

    • Classes support type checking and casting (is, as)
    • Structs do not support type casting
    • Example:
      swift
      let vehicle: Vehicle = Car(brand: "Toyota") if let car = vehicle as? Car { print(car.brand) }
  4. Reference Counting:

    • Classes use ARC (Automatic Reference Counting) for memory management
    • Structs don't need reference counting, allocated directly on the stack
    • Classes can cause retain cycles, need to use weak or unowned
  5. Deinitializers:

    • Classes can define deinitializers (deinit)
    • Structs cannot define deinitializers
    • Example:
      swift
      class FileHandler { let fileHandle: FileHandle init(path: String) { self.fileHandle = FileHandle(forReadingAtPath: path)! } deinit { fileHandle.closeFile() } }

Scenarios for choosing structs:

  1. Data models are primarily value types
  2. Data needs to exist independently without being accidentally modified
  3. Data is relatively small with low copying cost
  4. Inheritance is not needed
  5. Need thread-safe operations
  6. Need to compare value equality

Scenarios for choosing classes:

  1. Need inheritance and polymorphism
  2. Need to share state
  3. Data is large with high copying cost
  4. Need to control lifecycle and memory management
  5. Need to use identity comparison
  6. Need to use deinitializers

Best Practices:

  1. Prioritize using structs, only use classes when reference type characteristics are needed
  2. Use structs for simple data models
  3. Use classes for objects with identity and behavior
  4. Use classes when inheritance is needed
  5. Be aware of potential retain cycle issues with classes
标签:Swift