Enum trong Swift — nó là gì, cú pháp và cách dùng

Tác giả: IT Sectr Đã đăng: 2026-06-17 Thời gian đọc: 6 phút

Enum trong Swift là một kiểu hợp nhất một nhóm các giá trị liên quan dưới một tên duy nhất. Khác với C và Objective-C, nơi enum chỉ là một tập hợp các hằng số nguyên, Swift cung cấp enumeration hạng nhất với associated values, raw values, phương thức và hỗ trợ giao thức. Theo Apple, 2026, enum là một trong những công cụ chính để mô hình hóa trạng thái an toàn kiểu trong phát triển iOS.

Các điểm chính

  • Enum — một kiểu cho nhóm các giá trị liên quan, đảm bảo an toàn kiểu
  • Raw Values — giá trị cùng kiểu được gán cho tất cả các case enumeration
  • Associated Values — các kiểu dữ liệu khác nhau được gắn riêng cho từng case
  • Case được khai báo bằng từ khóa case và có thể chứa phương thức
  • Switch với enum yêu cầu trình biên dịch kiểm tra đầy đủ tất cả các trường hợp

Enum trong Swift là gì?

Enum (enumeration) là một kiểu dữ liệu tùy chỉnh hợp nhất một tập hợp hữu hạn các biến thể loại trừ lẫn nhau. Trong Swift, enum không chỉ là các hằng số số, mà là một kiểu hoàn chỉnh với logic riêng.

Mỗi biến thể của enumeration được gọi là một case. Khác với Objective-C, nơi enum chỉ là kiểu số nguyên, Swift cho phép mỗi case lưu trữ dữ liệu riêng và có phương thức.

Theo Apple, enum trong Swift hỗ trợ generic, bộ khởi tạo, thuộc tính tính toán và tuân thủ giao thức — giúp nó có thể áp dụng để mô hình hóa trạng thái, lỗi, tùy chọn và máy trạng thái hữu hạn.

Sử dụng enum bất cứ nơi nào bạn cần biểu diễn một tập hợp hữu hạn các biến thể loại trừ lẫn nhau: trạng thái màn hình, loại lỗi, hướng, tùy chọn lọc.

Cú pháp khai báo enum

Enum được khai báo bằng từ khóa enum theo sau là tên và phần thân trong dấu ngoặc nhọn.

swift
enum CompassDirection {
    case north
    case south
    case east
    case west
}

Case có thể được khai báo trên một dòng duy nhất, cách nhau bằng dấu phẩy:

swift
enum Planet {
    case mercury, venus, earth, mars, jupiter, saturn, uranus, neptune
}

Để truy cập một case, sử dụng cú pháp dấu chấm sau kiểu đã biết:

swift
let direction = CompassDirection.north
// Đã biết kiểu — cú pháp rút gọn có sẵn:
var currentPlanet = .earth

Khi một biến được gán kiểu enum đã biết, Swift tự động suy luận kiểu, cho phép bỏ qua tên enumeration khi truy cập các case.

Raw Values trong enumeration

Raw Values là các giá trị của một kiểu duy nhất được gán cho mỗi case enum. Khác với associated values, raw values có cùng kiểu cho tất cả các case và được xác định tại thời điểm khai báo.

swift
enum HTTPStatusCode: Int {
    case ok = 200
    case notFound = 404
    case internalServerError = 500
}

let code = HTTPStatusCode.notFound
print(code.rawValue) // 404

Đối với raw values là số nguyên, Swift tự động tăng giá trị nếu chỉ có giá trị đầu tiên được đặt rõ ràng:

swift
enum Status: Int {
    case pending = 1
    case active      // 2
    case completed   // 3
}

Raw values có thể thuộc các kiểu Int, String, Character hoặc bất kỳ kiểu nào tuân thủ giao thức RawRepresentable. Swift tự động tạo bộ khởi tạo init? để tạo enum từ raw value — thuận tiện cho việc phân tích dữ liệu từ API.

Associated Values trong enum

Associated Values cho phép gắn các kiểu dữ liệu khác nhau vào từng case enum riêng lẻ. Khác với raw values, associated values có thể khác nhau về kiểu và số lượng.

swift
enum NetworkError {
    case timeout(seconds: Int)
    case httpError(code: Int, message: String)
    case noConnection
    case unknown(error: Error)
}

Khi xử lý với switch, associated values được trích xuất thông qua việc gán vào biến hoặc hằng số:

swift
let error = NetworkError.httpError(code: 403, message: "Forbidden")

switch error {
case .timeout(let seconds):
    print("Hết thời gian chờ sau \(seconds)s")
case .httpError(let code, let message):
    print("HTTP \(code): \(message)")
case .noConnection:
    print("Không có kết nối")
case .unknown(let err):
    print("Không xác định: \(err.localizedDescription)")
}

Theo tài liệu Apple, associated values biến enum thành một công cụ biểu cảm để mô hình hóa các trạng thái phức tạp mà không cần tạo các kiểu wrapper riêng biệt. Sử dụng chúng cho các kịch bản giống Result và mô hình hóa lỗi có ngữ cảnh.

Enum đệ quy (indirect)

Enum đệ quy — một enumeration mà các case của nó tham chiếu đến chính kiểu enum. Các case như vậy được đánh dấu bằng từ khóa indirect.

swift
indirect enum LinkedList<T> {
    case empty
    case node(value: T, next: LinkedList<T>)
}

Sử dụng indirect trước enum đánh dấu tất cả các case là đệ quy. Ngoài ra, bạn có thể chỉ đánh dấu một case cụ thể bằng indirect:

swift
enum ArithmeticExpression {
    case number(Int)
    indirect case addition(ArithmeticExpression, ArithmeticExpression)
    indirect case multiplication(ArithmeticExpression, ArithmeticExpression)
}

Swift sử dụng indirect để lưu trữ các case đệ quy dưới dạng tham chiếu (ngữ nghĩa tham chiếu) thay vì giá trị — điều này ngăn kích thước enum vô hạn trên stack. Enum đệ quy được sử dụng rộng rãi trong việc xây dựng cây, danh sách liên kết và AST.

Enum và giao thức

Enum có thể tuân thủ giao thức giống như cấu trúc và lớp. Đây là một tính năng chính của lập trình hướng giao thức trong Swift.

swift
protocol Describable {
    var description: String { get }
}

enum PaymentMethod: Describable {
    case creditCard(last4: String)
    case applePay
    case bankTransfer

    var description: String {
        switch self {
        case .creditCard(let last4):
            return "Card ending in \(last4)"
        case .applePay:
            return "Apple Pay"
        case .bankTransfer:
            return "Bank Transfer"
        }
    }
}

Enum cũng có thể tuân thủ giao thức Cocoa — ví dụ, CaseIterable để tự động tạo tập hợp tất cả các case, hoặc Codable để tuần tự hóa. Điều này làm cho enum trở thành một khối xây dựng linh hoạt trong các ứng dụng Swift.

Câu hỏi thường gặp

Enum khác với struct trong Swift như thế nào?

Enum là một kiểu với tập hợp hữu hạn các biến thể loại trừ lẫn nhau, trong khi struct là kiểu với tập hợp thuộc tính tùy ý. Enum không thể có stored properties nhưng hỗ trợ computed properties và phương thức.

Một enum có thể có cả raw values và associated values cùng lúc không?

Không, một enum không thể có cả raw values và associated values cùng lúc. Raw values là giá trị cùng kiểu cho tất cả case, còn associated values là dữ liệu riêng cho từng case. Hai cơ chế này loại trừ lẫn nhau.

Làm thế nào để lấy mảng tất cả các case của enum?

Thêm tuân thủ giao thức CaseIterable. Swift sẽ tự động tạo thuộc tính allCases, trả về một tập hợp tất cả các case theo thứ tự khai báo. Điều này thuận tiện cho việc lặp qua tất cả các biến thể.

Có bắt buộc phải sử dụng switch để xử lý enum không?

Switch là cách an toàn nhất vì trình biên dịch kiểm tra tính đầy đủ. Bạn có thể sử dụng if case để kiểm tra một case hoặc == cho enum không có associated values.

Có thể tạo enum với generic không?

, enum hỗ trợ generic: enum Result<T, E> { case success(T); case failure(E) }. Điều này cho phép tạo các cấu trúc generic an toàn kiểu để xử lý thành công và lỗi.

Tổng kết

  • Enum trong Swift là một kiểu hoàn chỉnh hỗ trợ phương thức, generic và giao thức
  • Raw Values cho phép đặt giá trị cùng kiểu cho tất cả case
  • Associated Values cho phép gắn dữ liệu khác nhau vào từng case
  • Case Indirect cần thiết cho cấu trúc đệ quy trong enum
  • Giao thức có thể được enum triển khai — đây là nền tảng của POP trong Swift
  • Switch với enum đảm bảo xử lý đầy đủ tại thời điểm biên dịch
  • Sử dụng enum để mô hình hóa trạng thái hữu hạn và các tùy chọn an toàn kiểu

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.

Thảo luận dự án

Đọc thêm