+2

Tìm hiểu về Properties trong ngôn ngữ Swift

Mayfest2023

Tổng quan

Trong Swift, properties (thuộc tính) được sử dụng để định nghĩa và truy cập vào các giá trị của một kiểu dữ liệu. Properties có thể thuộc về các lớp, cấu trúc hoặc đối tượng đơn lẻ, và chúng có thể là các giá trị (stored properties) hoặc tính toán (computed properties). Dưới đây là một số khái niệm cơ bản về properties trong Swift, chúng ta cùng nhau tìm hiểu nhé.

Properties

1. Stored Properties (thuộc tính lưu trữ)

  • Là các thuộc tính lưu trữ giá trị trực tiếp và liên kết với một lớp hoặc cấu trúc.
  • Có thể là biến (variable) hoặc hằng số (constant).
  • Được khởi tạo bằng giá trị mặc định hoặc trong constructor.
class Person {
    var name: String // Stored property là biến (variable)
    let age: Int     // Stored property là hằng số (constant)
    
    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }
}

var person = Person(name: "John", age: 25)
person.name = "Steve"
print(person.name) // Result: Steve
print(person.age)  // Result: 25

2. Computed Properties (thuộc tính tính toán)

  • Là các thuộc tính không lưu trữ giá trị, mà tính toán giá trị dựa trên các giá trị khác.
  • Cung cấp một getter để truy xuất giá trị và có thể cung cấp một setter để thiết lập giá trị mới.
  • Thường được sử dụng khi bạn muốn thực hiện các tính toán phức tạp hoặc thay đổi giá trị của các thuộc tính khác.
struct Rectangle {
    var width: Double
    var height: Double
    
    var area: Double { // Computed property
        return width * height
    }
}

var rectangle = Rectangle(width: 10.0, height: 5.0)
print(rectangle.area) // Result: 50.0

rectangle.width = 8.0
print(rectangle.area) // Result: 40.0

Trong ví dụ trên, khi bạn gọi rectangle.area thì giá trị của area sẽ được tính toán dự trên widthheight của struct Rectangle.

3. Property Observers (quan sát/lắng nghe thuộc tính)

  • Là các khối mã được thực thi khi giá trị của một thuộc tính thay đổi.
  • Cung cấp các trình xử lý để phản ứng khi thuộc tính được thiết lập hoặc trước và sau khi thuộc tính thay đổi.
  • Property observers chỉ có thể được sử dụng với stored properties.
class StepCounter {
    var totalSteps: Int = 0 {
        willSet(newTotalSteps) {
            print("About to set totalSteps to \(newTotalSteps)")
        }
        
        didSet {
            if totalSteps > oldValue {
                print("Added \(totalSteps - oldValue) steps")
            }
        }
    }
}

let stepCounter = StepCounter()

stepCounter.totalSteps = 10
// Result:
// About to set totalSteps to 10
// Added 10 steps

stepCounter.totalSteps = 20
// Result:
// About to set totalSteps to 20
// Added 10 steps

Trong ví dụ trên, khi bạn gán dữ liệu cho thuộc tính totalSteps của struct StepCounter thì các property observers willSetdidSet sẽ được gọi và triển khai các logic statement bên trong nó.

4. Property Wrappers (đóng gói thuộc tính)

Property Wrappers (bọc thuộc tính) là một tính năng mạnh mẽ trong Swift từ phiên bản 5.1 trở đi. Property Wrappers cho phép bạn đóng gói (encapsulate) các logic xử lý liên quan đến thuộc tính vào trong một bọc (wrapper), làm cho việc quản lý và thay đổi các thuộc tính dễ dàng hơn. Property Wrappers có thể được áp dụng cho cả stored properties và computed properties.

Để tạo một Property Wrapper, bạn cần định nghĩa một cấu trúc (struct) hoặc một lớp (class) tuân thủ giao thức PropertyWrapper. Cấu trúc này phải có một thuộc tính wrappedValue và có thể triển khai các getter và setter để xử lý việc truy cập và thiết lập giá trị của thuộc tính gốc.

Dưới đây là một ví dụ đơn giản về Property Wrapper có tên là Capitalized để chuyển đổi chuỗi nhập vào thành chữ hoa:

@propertyWrapper
struct Capitalized {
    private(set) var value: String = ""
    
    var wrappedValue: String {
        get { return value }
        set { value = newValue.uppercased() }
    }
    
    init(wrappedValue: String) {
        self.wrappedValue = wrappedValue.uppercased()
    }
}

struct Person {
    @Capitalized var name: String
}

var person = Person(name: "john")
print(person.name) // Result: "JOHN"

person.name = "emma"
print(person.name) // Result: "EMMA"

Trong ví dụ trên, @Capitalized là một Property Wrapper được áp dụng cho thuộc tính name của struct Person. Khi giá trị của name được thiết lập, Property Wrapper sẽ tự động chuyển đổi giá trị thành chữ hoa trước khi lưu vào wrappedValue.

Property Wrappers cung cấp khả năng linh hoạt và tùy chỉnh mạnh mẽ. Bạn có thể thêm các trình xử lý trước và sau khi thiết lập giá trị, xác định các cài đặt mặc định, kiểm tra giá trị hợp lệ và thực hiện các tác vụ khác. Bạn cũng có thể xác định nhiều Property Wrappers cho cùng một thuộc tính để áp dụng các luật và logic khác nhau.

Property Wrappers là một phần quan trọng của Swift và giúp bạn tạo ra mã linh hoạt, sạch sẽ và dễ bảo trì. Đây chỉ là một ví dụ cơ bản về Property Wrappers, và Swift cung cấp nhiều tính năng và khả năng tùy chỉnh khác để bạn có thể tận dụng toàn.

Tổng kết, tài liệu tham khảo


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí