Mộc Viên's Blog Mộc Viên's Blog
Cách sử dụng associatedtype trong protocol?

Cách sử dụng associatedtype trong protocol?

Ngày đăng:

Cách sử dụng associatedtype trong protocol?

Trong Swift, associatedtype được sử dụng trong protocol để định nghĩa một kiểu dữ liệu liên kết (associated type), giúp protocol trở nên linh hoạt hơn mà không cần chỉ định trước một kiểu dữ liệu cụ thể.

Mở rộng Giao thức trong Swift 6.0: Những Thủ Thuật Mới
Bài viết “Protocol Extensions in Swift 6.0: New Tricks” của Adi Mizrahi trên Medium thảo luận về những cải tiến trong Swift 6.0 liên quan đến mở rộng protocol, giúp lập trình viên viết mã sạch hơn và tái sử dụng hiệu quả hơn. Tổng quan về Lập

1. Cách sử dụng cơ bản

Khi một protocol có associatedtype, kiểu dữ liệu đó sẽ được quyết định bởi class, struct hoặc enum tuân theo protocol đó.

protocol Container {
    associatedtype Item
    func add(_ item: Item)
    func getAll() -> [Item]
}

Ở đây, Container là một protocol định nghĩa một kiểu Item nhưng chưa chỉ định kiểu cụ thể.

2. Triển khai protocol có associatedtype

Khi một struct hoặc class tuân theo Container, nó phải xác định Item là kiểu dữ liệu cụ thể nào:

struct IntContainer: Container {
    typealias Item = Int  // Không bắt buộc phải khai báo typealias, Swift tự suy luận được.
    
    private var items: [Int] = []

    func add(_ item: Int) {
        items.append(item)
    }

    func getAll() -> [Int] {
        return items
    }
}

Hoặc với kiểu generic:

struct GenericContainer<T>: Container {
    typealias Item = T
    
    private var items: [T] = []

    func add(_ item: T) {
        items.append(item)
    }

    func getAll() -> [T] {
        return items
    }
}

3. Sử dụng với where để ràng buộc kiểu

Bạn có thể ràng buộc associatedtype bằng where để yêu cầu kiểu đó tuân theo một protocol khác:

protocol Identifiable {
    var id: String { get }
}

protocol Repository {
    associatedtype Model: Identifiable
    func getById(_ id: String) -> Model?
}

struct User: Identifiable {
    let id: String
    let name: String
}

struct UserRepository: Repository {
    typealias Model = User
    
    private var users: [User] = [
        User(id: "1", name: "Alice"),
        User(id: "2", name: "Bob")
    ]

    func getById(_ id: String) -> User? {
        return users.first { $0.id == id }
    }
}

4. Lưu ý khi sử dụng associatedtype

  • Một protocol có associatedtype không thể được sử dụng trực tiếp làm kiểu dữ liệu (Container không thể dùng làm kiểu của biến).
  • Để dùng một protocol với associatedtype, có thể sử dụng generic hoặc type erasure (AnyContainer).

Ví dụ về type erasure:

struct AnyContainer<T>: Container {
    typealias Item = T

    private let _add: (T) -> Void
    private let _getAll: () -> [T]

    init<C: Container>(_ container: C) where C.Item == T {
        _add = container.add
        _getAll = container.getAll
    }

    func add(_ item: T) {
        _add(item)
    }

    func getAll() -> [T] {
        return _getAll()
    }
}

Hy vọng giúp bạn hiểu rõ hơn về associatedtype trong Swift!

Swift - Mộc Viên’s Blog

Gần đây