struct — khái niệm, các điểm chính và cú pháp trong Swift

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

Struct là một kiểu giá trị (value type) trong ngôn ngữ Swift, các thể hiện của nó được sao chép khi truyền giữa các phần của mã. Không giống như lớp, cấu trúc không hỗ trợ kế thừa, nhưng chúng triển khai giao thức, chứa thuộc tính và phương thức, và cung cấp quản lý bộ nhớ có thể dự đoán mà không cần ARC. Theo Swift Programming Language Guide, 2026, struct là khối xây dựng cơ bản của Swift — ngay cả các kiểu chuẩn Int, String, Array và Dictionary cũng được triển khai dưới dạng cấu trúc. Ngôn ngữ này khuyến nghị cấu trúc là lựa chọn ưu tiên cho mô hình hóa dữ liệu.

Các điểm chính

  • Struct là kiểu giá trị trong Swift, được sao chép khi gán và truyền theo giá trị, không phải theo tham chiếu.
  • Copy-on-Write là tối ưu hóa trong đó việc sao chép dữ liệu thực tế chỉ xảy ra khi giá trị được sửa đổi, không phải khi gán.
  • Mutating là từ khóa cần thiết cho các phương thức sửa đổi thuộc tính của cấu trúc.
  • Giao thức — cấu trúc có thể triển khai giao thức và phần mở rộng, mang lại sự linh hoạt mà không cần kế thừa.
  • An toàn — không có vòng lặp tham chiếu làm cho cấu trúc được ưa chuộng cho mã đa luồng và mô hình dữ liệu.

Struct trong Swift là gì?

Struct (cấu trúc) là một kiểu dữ liệu tổng hợp trong Swift nhóm các thuộc tính và phương thức liên quan thành một thực thể duy nhất. Không giống như lớp, cấu trúc là value types: khi được truyền vào hàm hoặc gán cho biến mới, một bản sao độc lập của cấu trúc được tạo ra, không phải tham chiếu đến đối tượng gốc.

Swift sử dụng cấu trúc cho tất cả kiểu nguyên thủy: Int, Double, String, Bool, Array, Dictionary và Set. Điều này có nghĩa là ngay cả một Int cơ bản cũng hoạt động như một cấu trúc — một bản sao được tạo ra khi gán. Nhà phát triển có thể định nghĩa cấu trúc riêng với bất kỳ tập hợp thuộc tính và phương thức nào.

Theo Swift Evolution (SE-0143), quyết định triển khai các kiểu chuẩn dưới dạng cấu trúc được thúc đẩy bởi hiệu suất và khả năng dự đoán. Value types không tạo vòng lặp tham chiếu, không yêu cầu đếm tham chiếu ARC và đảm bảo rằng việc sửa đổi bản sao sẽ không ảnh hưởng đến bản gốc — điều này cực kỳ quan trọng cho tính bất biến của dữ liệu trong các tình huống đa luồng.

Struct như một value type

Ngữ nghĩa value type là sự khác biệt chính giữa struct và class. Khi bạn gán một cấu trúc cho biến mới hoặc truyền nó vào hàm, Swift tạo một bản sao độc lập của tất cả dữ liệu. Mọi thay đổi trong bản sao không ảnh hưởng đến bản gốc, loại bỏ các tác dụng phụ điển hình của kiểu tham chiếu.

swift
// Ví dụ về ngữ nghĩa value type
struct Point {
    var x: Double
    var y: Double
}

var p1 = Point(x: 10, y: 20)
var p2 = p1        // p2 là bản sao độc lập của p1
p2.x = 99            // Chỉ p2 thay đổi
print(p1.x)         // 10 — p1 không thay đổi
print(p2.x)         // 99

Tối ưu hóa Copy-on-Write

Swift sử dụng Copy-on-Write (COW) để tối ưu hóa việc sao chép. Nếu nhiều biến tham chiếu đến cùng một cấu trúc nhưng không biến nào sửa đổi dữ liệu, sẽ không có bản sao thực tế nào xảy ra. Swift chia sẻ bộ nhớ giữa các biến cho đến lần thay đổi đầu tiên — sau đó một bản sao thực sự được tạo ra. Điều này ngăn chặn các thao tác cấp phát quá mức và tăng tốc làm việc với bộ sưu tập.

Tính khả biến và phương thức mutating

Theo mặc định, các phương thức của cấu trúc không thể sửa đổi thuộc tính của nó — Swift yêu cầu từ khóa mutating rõ ràng cho các phương thức thực hiện thay đổi. Hạn chế này bảo vệ khỏi sự thay đổi ngẫu nhiên và làm cho mã có thể dự đoán: nếu một phương thức không được đánh dấu là mutating, bạn được đảm bảo sẽ không thay đổi cấu trúc.

Mutating trong hành động

Khi bạn thêm từ khóa mutating trước một phương thức, Swift có khả năng ghi các giá trị mới vào thuộc tính của cấu trúc. Trên thực tế, phương thức thậm chí có thể thay thế hoàn toàn thể hiện cấu trúc bằng một thể hiện mới thông qua self =. Cơ chế này được sử dụng, ví dụ, trong các kiểu Option và Result.

swift
// Struct với phương thức mutating
struct Counter {
    private var value: Int = 0

    // Phương thức mutating — có thể sửa đổi thuộc tính
    mutating func increment() {
        value += 1
    }

    // Phương thức mutating có thể thay thế hoàn toàn self
    mutating func reset() {
        self = Counter()
    }

    // Phương thức non-mutating — chỉ đọc
    func currentValue() -> Int {
        return value
    }
}

var counter = Counter()
counter.increment()
print(counter.currentValue())  // 1
counter.reset()
print(counter.currentValue())  // 0

Quy tắc cho mutating: cấu trúc phải được khai báo với var, không phải let — một cấu trúc hằng không thể gọi phương thức mutating. Trình biên dịch kiểm tra điều này tại thời điểm xây dựng: cố gắng gọi phương thức mutating trên hằng let sẽ dẫn đến lỗi biên dịch.

Struct vs Class: so sánh

Sự lựa chọn giữa struct và class là một trong những quyết định cơ bản trong Swift. Cả hai kiểu đều có thể chứa thuộc tính, phương thức, bộ khởi tạo và triển khai giao thức, nhưng có sự khác biệt cơ bản về ngữ nghĩa bộ nhớ, kế thừa và quản lý vòng đời.

Đặc điểmstructclass
KiểuValue type (sao chép)Reference type (tham chiếu)
Kế thừaKhông hỗ trợHỗ trợ
ARC / đếm tham chiếuKhông yêu cầuARC yêu cầu
Hủy khởi tạoKhông hỗ trợHỗ trợ deinit
Sửa đổi thuộc tính trong hằngChỉ qua varCó thể qua let (tham chiếu là hằng)
Ép kiểuKhông hỗ trợHỗ trợ
Lưu trữ trong bộ sưu tậpLưu trực tiếp (giá trị)Lưu dưới dạng tham chiếu (con trỏ)

Cấu trúc được ưa chuộng khi dữ liệu không yêu cầu kế thừa, không nên có danh tính chia sẻ (ví dụ: tọa độ, kích thước, cấu hình) và được truyền giữa các mô-đun. Lớp được chọn cho các thành phần UI (UIView, UIViewController), singleton và các đối tượng có danh tính chia sẻ.

Khi nào chọn struct

Apple khuyến nghị sử dụng struct như kiểu mặc định cho mô hình hóa dữ liệu trong Swift. Cấu trúc phù hợp với hầu hết các tình huống nhờ ngữ nghĩa sao chép có thể dự đoán và không có chi phí đếm tham chiếu. Hãy xem các trường hợp điển hình khi struct là lựa chọn tối ưu.

Mô hình dữ liệu không cần kế thừa

Nếu một thực thể chứa dữ liệu không cần kế thừa (Product, User, Order, Point), hãy sử dụng struct. Trình biên dịch tự động tạo memberwise initializer — bạn không cần viết init thủ công. Equatable và Hashable cũng được tự động triển khai cho các cấu trúc có tất cả thuộc tính tuân thủ các giao thức này.

Dữ liệu bất biến

Cho cấu hình, cài đặt và cờ không thay đổi sau khi tạo, struct tốt hơn class. Một cấu trúc hằng (let) đảm bảo tính bất biến của tất cả các trường lồng nhau — trong class, điều này chỉ áp dụng cho tham chiếu, không phải nội dung của đối tượng.

Mã đa luồng

Cấu trúc an toàn trong môi trường đa luồng nhờ ngữ nghĩa giá trị. Mỗi luồng nhận được một bản sao độc lập của dữ liệu và không ảnh hưởng đến các luồng khác. Điều kiện đua giữa các luồng là không thể đối với value types, làm cho struct trở thành lựa chọn ưa chuộng cho các mô hình trong SwiftUI (ObservableObject yêu cầu class, nhưng @State sử dụng struct).

swift
// Ví dụ sử dụng struct cho mô hình dữ liệu
struct User: Codable, Identifiable {
    let id: UUID
    var name: String
    var email: String
    var isPremium: Bool

    // Thuộc tính tính toán — non-mutating
    var displayName: String {
        isPremium ? "\(name) ⭐️" : name
    }
}

// Trình khởi tạo memberwise tự động
let user = User(
    id: UUID(),
    name: "Alice",
    email: "alice@example.com",
    isPremium: true
)

// Sao chép an toàn cho đa luồng
var userCopy = user
userCopy.isPremium = false
// user.isPremium vẫn là true

Sử dụng class khi bạn cần kế thừa (các thành phần UIKit/AppKit), danh tính chia sẻ (delegate, observer) hoặc vòng đời đối tượng được kiểm soát (deinit). Mọi thứ khác — hãy sử dụng struct.

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

Struct trong Swift là gì?

Struct trong Swift là kiểu giá trị được sao chép khi truyền giữa các phần của mã. Cấu trúc có thể chứa thuộc tính, phương thức, bộ khởi tạo và triển khai giao thức. Các kiểu cơ bản của Swift (Int, String, Array) được triển khai dưới dạng cấu trúc.

Sự khác biệt giữa struct và class trong Swift là gì?

Struct là value type (sao chép khi gán), không hỗ trợ kế thừa và không yêu cầu ARC. Class là reference type (truyền theo tham chiếu), hỗ trợ kế thừa, hủy khởi tạo và đếm tham chiếu. Các nhà phát triển khuyến nghị struct là kiểu mặc định.

Mutating trong struct Swift là gì?

Mutating là từ khóa chỉ ra rằng phương thức của cấu trúc có thể sửa đổi thuộc tính của nó. Không có mutating, trình biên dịch cấm sửa đổi trường. Phương thức mutating chỉ có thể được gọi trên các biến khai báo với var, không phải let.

Copy-on-Write trong Swift là gì?

Copy-on-Write (COW) là tối ưu hóa của Swift cho cấu trúc trong đó việc sao chép dữ liệu thực tế được hoãn lại cho đến lần thay đổi đầu tiên. Miễn là tất cả các biến chỉ đọc cấu trúc, chúng chia sẻ một vùng bộ nhớ duy nhất. Điều này cải thiện hiệu suất khi làm việc với các bộ sưu tập lớn.

Khi nào sử dụng struct và khi nào sử dụng class trong Swift?

Sử dụng struct cho mô hình dữ liệu không cần kế thừa, cấu hình, DTO và tình huống đa luồng. Sử dụng class cho các thành phần UI UIKit/AppKit, singleton, thực thể có danh tính chia sẻ (delegate, observer) và đối tượng cần hủy khởi tạo.

Tổng kết

  • Struct là kiểu giá trị trong Swift được sao chép khi gán, cung cấp hành vi có thể dự đoán không có tác dụng phụ giữa các bản sao.
  • Copy-on-Write tối ưu hóa hiệu suất của cấu trúc — việc sao chép thực tế chỉ xảy ra ở lần thay đổi đầu tiên, không phải mỗi lần gán.
  • Các kiểu chuẩn của Swift — Int, String, Array, Dictionary — được triển khai dưới dạng cấu trúc, đảm bảo ngữ nghĩa giá trị cho tất cả các thao tác cơ bản.
  • Mutating là từ khóa bắt buộc cho các phương thức sửa đổi thuộc tính của cấu trúc; chỉ có thể được gọi trên các thể hiện var.
  • Cấu trúc không hỗ trợ kế thừa nhưng triển khai giao thức và có thể sử dụng phần mở rộng để thêm chức năng.
  • Equatable và Hashable được tự động triển khai cho các cấu trúc có tất cả thuộc tính tuân thủ các giao thức này — đơn giản hóa việc so sánh và sử dụng trong bộ sưu tập.
  • Apple khuyến nghị struct là kiểu mặc định — chỉ sử dụng class khi cần kế thừa, danh tính chia sẻ hoặc vòng đời đối tượng được kiểm soá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.

Thảo luận dự án

Đọc thêm