Thận trọng: điều khoản của giáo dân phía trước.
Lời giải thích này không đúng một cách nghiêm ngặt ở cấp mã nitty-gritty nhất. Tuy nhiên, nó đã được đánh giá bởi một người thực sự làm việc trên Swift và anh ấy nói rằng nó đủ tốt như một lời giải thích cơ bản.
Vì vậy, tôi muốn cố gắng trả lời đơn giản và trực tiếp câu hỏi "tại sao".
Nói chính xác: tại sao chúng ta phải đánh dấu các hàm struct mutating
khi chúng ta có thể thay đổi các tham số struct mà không cần sửa đổi từ khóa nào?
Vì vậy, bức tranh toàn cảnh, nó liên quan rất nhiều đến triết lý giữ Swift nhanh chóng.
Bạn có thể nghĩ về nó giống như vấn đề quản lý các địa chỉ vật lý thực tế. Khi bạn thay đổi địa chỉ của mình, nếu có nhiều người có địa chỉ hiện tại của bạn, bạn phải thông báo cho tất cả họ rằng bạn đã chuyển đi. Nhưng nếu không ai có địa chỉ hiện tại của bạn, bạn có thể di chuyển đến bất cứ đâu bạn muốn và không ai cần biết.
Trong tình huống này, Swift giống như một bưu điện. Nếu nhiều người có nhiều mối quan hệ di chuyển nhiều nơi, nó có chi phí thực sự cao. Nó phải trả một lượng lớn nhân viên để xử lý tất cả các thông báo đó và quá trình này chiếm rất nhiều thời gian và công sức. Đó là lý do tại sao trạng thái lý tưởng của Swift là mọi người trong thị trấn của nó có càng ít liên hệ càng tốt. Sau đó, nó không cần một nhân viên lớn để xử lý các thay đổi địa chỉ và nó có thể làm mọi thứ khác nhanh hơn và tốt hơn.
Đây cũng là lý do tại sao những người dùng Swift đều say mê về các loại giá trị so với các loại tham chiếu. Về bản chất, các loại tham chiếu có nhiều "địa chỉ liên hệ" ở khắp nơi và các loại giá trị thường không cần nhiều hơn một vài. Loại giá trị là "Swift" -er.
Vì vậy, trở lại hình ảnh nhỏ: structs
. Các cấu trúc là một vấn đề lớn trong Swift vì chúng có thể làm hầu hết những thứ mà các đối tượng có thể làm, nhưng chúng là các kiểu giá trị.
Hãy tiếp tục tương tự địa chỉ thực bằng cách tưởng tượng một địa chỉ misterStruct
sống ở đó someObjectVille
. Ở đây có một chút tương tự, nhưng tôi nghĩ nó vẫn hữu ích.
Vì vậy, để mô hình hóa việc thay đổi một biến trên a struct
, giả sử misterStruct
có tóc màu xanh lá cây và nhận được lệnh chuyển sang tóc màu xanh lam. Như tôi đã nói, sự tương tự trở nên khó hiểu, nhưng điều xảy ra là thay vì thay misterStruct
tóc, người cũ chuyển ra ngoài và một người mới với mái tóc xanh chuyển đến, và người mới đó bắt đầu gọi họ misterStruct
. Không ai cần nhận thông báo thay đổi địa chỉ, nhưng nếu ai nhìn vào địa chỉ đó, họ sẽ thấy một anh chàng tóc xanh.
Bây giờ hãy mô hình hóa những gì sẽ xảy ra khi bạn gọi một hàm trên a struct
. Trong trường hợp này, nó giống như misterStruct
nhận được một đơn đặt hàng chẳng hạn changeYourHairBlue()
. Vì vậy, bưu điện đưa ra hướng dẫn misterStruct
"hãy thay đổi mái tóc của bạn thành màu xanh lam và cho tôi biết khi bạn hoàn thành."
Nếu anh ấy vẫn theo thói quen như trước đây, nếu anh ấy đang làm những gì anh ấy đã làm khi biến số bị thay đổi trực tiếp, điều misterStruct
sẽ làm là chuyển ra khỏi nhà của anh ấy và gọi cho một người mới với mái tóc xanh. Nhưng đó là vấn đề.
Mệnh lệnh là "hãy thay đổi mái tóc của bạn thành màu xanh lam và nói với tôi khi bạn hoàn thành," nhưng chính anh chàng màu xanh lá cây mới nhận được lệnh đó. Sau khi anh chàng da xanh chuyển đến, thông báo "công việc hoàn thành" vẫn phải được gửi lại. Nhưng anh chàng da xanh không biết gì về nó.
[Để thực sự hiểu ra điều tương tự này có điều gì đó khủng khiếp, điều về mặt kỹ thuật đã xảy ra với anh chàng tóc xanh là sau khi chuyển ra ngoài, anh ta ngay lập tức tự sát. Vì vậy, anh ta cũng không thể thông báo cho bất kỳ ai rằng nhiệm vụ đã hoàn thành ! ]
Để tránh vấn đề này, trong những trường hợp như thế này chỉ , Swift vừa đi vừa trực tiếp đến ngôi nhà tại địa chỉ đó và thực sự thay đổi mái tóc của cư dân hiện tại của . Đó là một quá trình hoàn toàn khác so với chỉ gửi một chàng trai mới.
Và đó là lý do tại sao Swift muốn chúng ta sử dụng mutating
từ khóa!
Kết quả cuối cùng trông giống với bất kỳ thứ gì liên quan đến cấu trúc: cư dân của ngôi nhà giờ có mái tóc màu xanh lam. Nhưng các quá trình để đạt được nó thực sự hoàn toàn khác nhau. Có vẻ như nó đang làm điều tương tự, nhưng nó đang làm một điều rất khác. Nó đang làm một điều mà các cấu trúc Swift nói chung không bao giờ làm.
Vì vậy, để cung cấp cho trình biên dịch kém một chút trợ giúp, và không khiến nó phải tìm ra liệu một hàm có tự thay đổi struct
hay không, đối với mỗi hàm struct đơn lẻ, chúng tôi được yêu cầu bỏ qua và sử dụng mutating
từ khóa.
Về bản chất, để giúp Swift nhanh chóng, tất cả chúng ta phải làm phần việc của mình. :)
BIÊN TẬP:
Này anh bạn / anh chàng đã phản đối tôi, tôi chỉ viết lại hoàn toàn câu trả lời của mình. Nếu nó phù hợp hơn với bạn, bạn sẽ loại bỏ phiếu phản đối?