Skip to Content

Generics trong Swift

1. Giới thiệu

Generics cho phép viết code linh hoạt, type-safe với nhiều kiểu dữ liệu.

2. Generic Function

func swapValues<T>(_ a: inout T, _ b: inout T) { let temp = a a = b b = temp } var x = 5, y = 10 swapValues(&x, &y) print(x, y) // 10, 5 var s1 = "Hello", s2 = "World" swapValues(&s1, &s2)

3. Generic Types

struct Stack<Element> { private var items: [Element] = [] mutating func push(_ item: Element) { items.append(item) } mutating func pop() -> Element? { items.popLast() } var top: Element? { items.last } } var intStack = Stack<Int>() intStack.push(1) intStack.push(2) print(intStack.pop()) // Optional(2)

4. Type Constraints

func findIndex<T: Equatable>(of value: T, in array: [T]) -> Int? { for (index, item) in array.enumerated() { if item == value { return index } } return nil } print(findIndex(of: 3, in: [1, 2, 3, 4, 5])) // Optional(2)

5. Multiple Constraints

func compare<T>(_ a: T, _ b: T) -> Bool where T: Comparable, T: Hashable { return a < b } // Hoặc func compare2<T: Comparable & Hashable>(_ a: T, _ b: T) -> Bool { return a < b }

6. Associated Types

protocol Container { associatedtype Item mutating func append(_ item: Item) var count: Int { get } subscript(i: Int) -> Item { get } } struct IntContainer: Container { typealias Item = Int private var items: [Int] = [] mutating func append(_ item: Int) { items.append(item) } var count: Int { items.count } subscript(i: Int) -> Int { items[i] } }

7. Generic Where Clauses

func allItemsMatch<C1: Container, C2: Container>( _ container1: C1, _ container2: C2 ) -> Bool where C1.Item == C2.Item, C1.Item: Equatable { guard container1.count == container2.count else { return false } for i in 0..<container1.count { if container1[i] != container2[i] { return false } } return true }

8. Extensions với Generics

extension Stack { var isEmpty: Bool { items.isEmpty } } extension Stack where Element: Equatable { func contains(_ item: Element) -> Bool { items.contains(item) } }

9. Generic Subscripts

extension Container { subscript<Indices: Sequence>(indices: Indices) -> [Item] where Indices.Iterator.Element == Int { var result: [Item] = [] for index in indices { result.append(self[index]) } return result } }

10. Opaque Types (some)

protocol Shape { func draw() -> String } struct Square: Shape { func draw() -> String { "◻️" } } // Opaque return type func makeShape() -> some Shape { return Square() } let shape = makeShape() print(shape.draw())

📝 Tóm tắt

  • Generic type parameter
  • : Protocol cho type constraints
  • where cho complex constraints
  • associatedtype trong protocols
  • Extensions với conditional constraints
  • some cho opaque types
Last updated on