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
: Protocolcho type constraintswherecho complex constraintsassociatedtypetrong protocols- Extensions với conditional constraints
somecho opaque types
Last updated on
Swift