Associated Values — một cơ chế Swift cho phép gắn dữ liệu tùy ý vào từng case enum riêng lẻ. Không giống như raw values, nơi tất cả các case đều có giá trị cùng loại, associated values có thể khác nhau về loại và số lượng cho mỗi case. Theo Apple Documentation, 2026, đây là khả năng quan trọng để mô hình hóa chính xác một lĩnh vực mà không cần tạo các kiểu wrapper bổ sung.
Những Điểm Chính
Associated Values là thông tin bổ sung mà một case enum có thể lưu trữ cùng với chính nó. Không giống như raw values, được cố định ở cấp khai báo, associated values được thiết lập khi tạo một phiên bản enum.
Hãy tưởng tượng mô hình hóa một phương thức thanh toán: case creditCard có thể lưu trữ 4 chữ số cuối và ngày hết hạn, trong khi case applePay không lưu trữ gì. Với associated values, điều này được triển khai một cách tự nhiên, không cần subclass hay trường tùy chọn.
Theo tài liệu Apple, associated values biến enum từ một tập hợp đơn giản các hằng số thành một kiểu dữ liệu đại số (sum type), đặc trưng của các ngôn ngữ hàm. Điều này nâng cao đáng kể khả năng biểu đạt của mã.
Associated Values được khai báo trong dấu ngoặc đơn sau case, chỉ định tên tham số và kiểu, giống như các hàm.
enum MediaFile {
case image(width: Int, height: Int, format: String)
case video(duration: Double, codec: String)
case audio(bitrate: Int)
case unknown
}
Khi tạo một phiên bản, associated values được truyền dưới dạng đối số:
let photo = MediaFile.image(width: 1920, height: 1080, format: "jpeg")
let clip = MediaFile.video(duration: 120.5, codec: "h264")
Swift không áp đặt hạn chế nào về số lượng hoặc loại associated values. Bạn có thể sử dụng generics, hàm đóng và các enum khác bên trong associated values. Điều này cho phép xây dựng các cấu trúc lồng nhau phức tạp.
Tên tham số của associated values được sử dụng làm nhãn đối số khi tạo phiên bản — điều này cải thiện khả năng đọc mã. Khi trích xuất qua switch, các tên đóng vai trò như tài liệu, làm rõ ý nghĩa của từng giá trị. Cách tiếp cận này làm cho mã tự ghi chú và giảm khả năng xảy ra lỗi khi so khớp dữ liệu. Điều này đặc biệt có giá trị trong phát triển nhóm các ứng dụng iOS lớn.
Switch là cách chính để trích xuất associated values. Các giá trị được liên kết với hằng số hoặc biến thông qua let hoặc var.
func describe(_ file: MediaFile) -> String {
switch file {
case .image(let w, let h, let fmt):
return "Image \(w)x\(h) .\(fmt)"
case .video(let duration, let codec):
return "Video \(duration)s, \(codec)"
case .audio(let bitrate):
return "Audio \(bitrate)kbps"
case .unknown:
return "Unknown format"
}
}
Swift hỗ trợ so khớp một phần — bạn có thể chỉ định các giá trị cụ thể cho associated values:
switch file {
case .image(let w, let h, "png"):
print("Hình ảnh PNG \(w)x\(h)")
case .image(1920, 1080, _):
print("Hình ảnh Full HD")
default:
break
}
Sử dụng ký tự đại diện (_) cho phép bỏ qua các associated values không cần thiết và các hằng số trong case cho phép bạn kiểm tra sự trùng khớp với các giá trị cụ thể.
Nhiều nhà phát triển mới bắt đầu nhầm lẫn associated values với raw values. Đây là các cơ chế khác nhau với các trường hợp sử dụng khác nhau.
| Đặc điểm | Raw Values | Associated Values |
|---|---|---|
| Kiểu dữ liệu | Một kiểu cho tất cả case | Kiểu khác nhau cho mỗi case |
| Thời điểm gán | Tại khai báo enum | Tại tạo phiên bản |
| Tính bắt buộc | Tất cả case đều có giá trị | Một số case có thể không có giá trị |
| Tương thích | Loại trừ lẫn nhau — không thể sử dụng đồng thời | |
Theo Swift Evolution, associated values được giới thiệu trong Swift 2.0 như một phần của việc thiết kế lại enum. Chúng cung cấp một cách tiếp cận đại số cho các kiểu, nơi mỗi case là một hàm tạo riêng biệt với chữ ký riêng của nó.
Associated Values được sử dụng tích cực trong các dự án iOS thực tế. Hãy xem xét ba tình huống điển hình.
enum APIResponse<T: Codable> {
case success(data: T, cached: Bool)
case failure(error: Error, retryAvailable: Bool)
case loading(progress: Double)
}
enum ViewState<T> {
case idle
case loading(message: String)
case loaded(data: T)
case error(message: String, retryAction: () -> Void)
}
Với associated values, enum trở thành một công cụ mạnh mẽ cho máy trạng thái: mỗi case là một trạng thái, associated values là tham số của trạng thái đó. Trình biên dịch đảm bảo rằng tất cả các chuyển tiếp đều được xử lý.
Để kiểm tra một case duy nhất mà không dùng switch, hãy sử dụng if case hoặc guard case. Cách này gọn nhẹ hơn khi bạn chỉ cần xử lý một tùy chọn.
let error = NetworkError.timeout(seconds: 30)
if case .timeout(let seconds) = error {
print("Yêu cầu đã hết thời gian sau \(seconds)s")
}
guard case .httpError(let code, _) = error else {
return
}
print("Lỗi HTTP với mã \(code)")
Câu Hỏi Thường Gặp
Có, một case có thể không có associated values — ví dụ: case unknown. Các case như vậy hoạt động như các case enum thông thường mà không có dữ liệu bổ sung. Điều này thuận tiện cho các trạng thái đánh dấu.
Swift không tự động tạo Equatable cho enum với associated values (trước Swift 4.2+). Thêm triển khai Equatable rõ ràng hoặc sử dụng switch để so sánh từng case tuần tự.
Có, associated values trong indirect enum là một kỹ thuật tiêu chuẩn để xây dựng cây và danh sách liên kết. Một case có thể chứa một associated value cùng loại được đánh dấu bằng indirect.
Associated Values an toàn về kiểu — mỗi case được đảm bảo chỉ có dữ liệu riêng của nó. Trong struct với các tùy chọn, mọi phiên bản đều chứa tất cả các trường và cần kiểm tra nil trong thời gian chạy.
Swift không tự động tạo Codable cho enum với associated values. Cần triển khai thủ công encode và decode thông qua switch trên các case sử dụng khóa mã hóa tùy chỉnh.
Tổng Kết
Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay
IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.
Đọc thêm