Một trong những cách mà Swift giúp cho chúng ta viết ra những dòng code tuyệt vời đó là thông quan khái niệm về kiểu giá trị, điều mà bị giới hạn bởi các trạng thái được chia sẻ thông qua các API. Bởi vì khi sử dụng kiểu dữ liệu giá trị, tất cả các mutation mặc đinh là được sẽ tạo ra giá trị được sao chép ở local và API mà chúng được mutation được đánh dấu là mutating.
Hàm mutating có nhiệm vụ gì ?
Một hàm được đánh dấu là mutating có thể thay đổi bất kỳ thuộc tính nào nằm trong giá trị của nó. Cụm từ “giá trị” thực chất là chìa khóa ở đây, kể từ khi định nghĩa về mutation của Swift chỉ áp dụng cho kiểu giá trị chứ không phải kiểu tham chiếu như class hoặc actor.
Ví dụ như hàm cancel nằm trong Meeting là mutating, vì nó thay đổi được giá trị của thuộc tính state và reminderDate
Ngoài việc thay đổi được thuộc tính, định nghĩa về mutating còn có thể gán được giá trị mới cho self, điều mà rất hữu ích cho việc thêm một hàm vào một enum.
Kỹ thuật trên còn hữu ích cho các kiểu giá trị khác, ví dụ như là struct, có thể thực sự hữu ích nếu chúng ta muốn khởi tạo lại giá trị của nó về mặc đinh. hoặc chúng ta muốn biến đổi nó thành một kiểu giá trị phức tạp khác.
Tạo mutation trong khởi
Trong khi các chức năng luôn luôn được đánh dấu công khai là mutating mỗi khi chúng ta muốn thay đổi giá trị của trạng thái nội tại của chúng, hàm khởi tạo luôn được biến đổi mặc định. Điều đó có nghĩa là thay vì gán giá trị khởi tạo giá trị của thuộc tính, thì chúng ta có thể biến đổi hàm này để tạo ra một giá trị khác tuy nhiên self vẫn phải được khởi tạo trước tiên.
Ví dụ, ProductGroup sẽ gọi hàm add của nó để thêm các product vào trong hàm khởi tạo của nó.
Thuộc tính Non-mutating
Cho đến giờ, chúng ta chỉ nói về định nghĩa mutating, nhưng Swift cũng đưa ra cho chúng ta cách để đánh dấu các thuộc tính non-mutating. Khi mà các ứng dụng của nó khá giới hạn so với mutating nhưng trong một số trường hợp nó vẫn khá hữu dụng.
Để ví dụ cho việc này, hãy nhìn vào một view code bằng SwiftUI, mà sẽ tăng giá trị của biến value mỗi khi nó được bấm.
Bây giờ, nếu như chúng ta nhìn vào phía trên nó không chỉ là một view SwiftUI, mà nó còn là một struct bình thường. Làm sao mà chúng ta có thể thay đổi thuộc tính value nằm trong closure như vậy mà không gọi đến mutating hoặc synchronous.
Câu trả lờ nằm trong phần khởi tạo State của wrappedValue, điều mà đã được đánh dấu là nonmuating keyword :
Ngoài ra chúng ta có thể sử dụng cách sau để tránh việc giá trị của thuộc tính bị thay đổi ở bên ngoài mà chỉ thay đổi giá trị thuộc tính trong code mà chúng ta xây dựng sẵn cho nó.
Đến đây là hết bài viết, cảm ơn các bạn đã đón xem.
REF : https://www.swiftbysundell.com/articles/mutating-and-nonmutating-swift-contexts/
Nguồn: viblo.asia