Contents
Chào mừng bạn đến với Fx Studio. Chủ đề bài viết lần này sẽ nói về một từ khóa khá phổ biến trong Swift, đó là Guard. Nếu bạn là một iOS developer, thì đã rất quen thuộc với Guard rồi. Và mục đích bài viết này sẽ giúp bạn hệ thống lại khi nào sẽ sử dụng Guard cho hiệu quả.
Còn nếu mọi việc đã ổn rồi, thì …
Bắt đầu thôi!
Chuẩn bị
Về mặt kiến thức, bạn chỉ cần biết sơ qua về Swift là ổn rồi. Nhưng nếu bạn chưa biết gì về Swift, thì có thể đọc qua bài viết ở link sau:
Về tools, bạn không cần quá lo lắng. Các Xcode bây giờ đều chạy tốt và có sẵn Guard trong Core rồi.
Guard Keyword
Khi học về Swift, bạn sẽ bắt gặp kiểu cú pháp này khá là nhiều trong các project.
func hello(name: String?) { guard let name = name else { return } print("Hello, \(name)") }
Đây chính là ví dụ minh họa đơn giản nhất cho việc sử dụng từ khóa guard
trong chương trình. Với Guard, bạn sẽ dùng kèm với các từ khóa khác, như là: else
, throw
, return
. Và chúng ta có thể chia chúng ra với 3 dạng mục đích chính.
- Exit Early
- Đây là cách sử dụng phổ biết nhất. Thường được áp dụng trong các fucntion. Với mục đích kết thúc sớm function đó, khi dữ liệu đầu vào của bạn là các Optionals.
- Validate Requirements
- Tiếp theo là cách dùng tinh tế hơn. Khi bạn muốn kiểm tra điều kiện và kết hợp với xử lý lỗi, thay vì
return
một cách vô hồn.
- Tiếp theo là cách dùng tinh tế hơn. Khi bạn muốn kiểm tra điều kiện và kết hợp với xử lý lỗi, thay vì
- Segment Logic
- Bản chất của nó cũng tương tự như
if else
, nên công dụng tiếp theo là điều hướng logic trong code. Bên cạnh đó, nó cũng bảo vệ các đoạn code của bạn, nhằm đảm bảo tính toàn vẹn của dữ liệu đầu vào.
- Bản chất của nó cũng tương tự như
Khá là hay phải không nào. Chúng ta sẽ tìm hiểu dần dần thông qua các ví dụ ở phần sau nhóe.
Else Throw
Để xóa đi ý niệm tồn tại lâu với return
, thì chúng ta cần tạo ra kết hợp giữa các từ khóa sau:
guard
+else
+throw
Mục đích chính là bạn sẽ không xử lý lỗi phát sinh tại function đó. Bạn chỉ cần chuyển giao nó về function cao hơn để giải quyết. Tham khảo đoạn code sau nhóe.
enum ValidationError: Error { case fullNameIsRequired case lastNameIsRequired } func validate(name: String) throws { guard name.count > 3 else { throw ValidationError.fullNameIsRequired } guard name.contains(" ") else { throw ValidationError.lastNameIsRequired } }
Trong ví dụ trên, bạn sẽ nhận ra rằng là chúng ta bắt 2 điều kiện cho cùng một biến name
, mặc dù name
không phải là Optional.
Ưu điểm của cách dùng này là:
- Xác định cụ thể lỗi nào cho biến đầu vào nào
- Vẫn đảm bảo tính toàn vẹn của các đoạn code ở dưới
- Kết hợp được nhiều xử lý cho nhiều điều kiện đầu vào
Let Optional
Đây là cách phổ biết nhất với Guard trong Swift. Nhiệm vụ chính của nó sẽ là unwrap optionals, cũng khá tương tự với if let
.
Bạn đã có ví dụ code về cách dùng này ở trên rồi. Ta sẽ xem lại ví dụ với cả 2 cách if let
& guard let
nhóe.
// guard let guard let name = name else { return } print("Hello, \(name)") // if let if let name = name { print("Hello, \(name)") }
Tùy vào ý nghĩa mà bạn muốn thể hiện, kết quả nhận được sẽ khác nhau. Với:
if let
: bạn đảm bảo được giá trị của biến trong phạm vi câu lệnhif
. Và sau khi thoát khỏi câu lệnhif
thì mọi thứ sẽ quay về lại như ban đầu.guard let
: bạn đảm bảo được giá trị của biến cho toàn bộ các phần phái dưới, sau khi thoát khỏi câu lệnh điều kiện. Biến mới sẽ đảm bảo giá trị và an toàn.
Multiple Conditions
Với các chương trình lớn, độ phức tạp về mặt logic cũng tăng theo. Nên đôi lúc bạn cần phải sử dụng nhiều điều kiện trong cùng 1 câu lệnh. Và khi bạn không cần quan tâm tới cụ thể từng lỗi do mỗi điều kiện gây ra, thì việc kết hợp chúng lại với nhau là giải pháp hợp lý nhất.
Công việc trên cũng khá là quen thuộc với bạn, nhưng khi bạn sử dụng thêm guard
thì bạn đảm bảo dữ liệu của mình với nhiều điều kiện một lúc. Xem ví dụ code sau nhóe!
class FormViewController: UIViewController { var hasEdits = true var forceSave = false // other functions func saveData(data: Data?) { // A guard statement with two conditions guard let data = data, hasEdits || forceSave else { return } // Handle data saving } }
Bạn sẽ sử dụng keyword ,
để tách biệt các điều kiện với nhau. Trong ví dụ, function saveData()
đã đảm bảo dữ liệu data
khi nó là một Optional. Và cũng đảm bảo với các điều kiện khác của class quy định.
Guard Available
Đôi lúc, function của bạn chỉ hoạt động trên một số version OS cụ thể. Thì bạn vẫn có thể áp dụng cú pháp guard #available
, vì bản chất guard
cũng tương tự if
mà thôi.
Xem ví dụ code nhóe!
func showTelephotoCamera() throws { guard #available(iOS 13, *) else { throw CameraError.deviceNotSupported } let cameraController = MyCameraViewController() cameraController.camera = .telephoto present( cameraController, animated: true, completion: nil ) }
Ý nghĩa to lớn nhất của cách dùng này là:
- Bạn không cần viết lại function hay bọc chúng trong
if
- Vẫn bảo vệ được các đoạn code phía dưới câu lệnh
guard
Case Enum
Đây là cách ít người sử dụng guard
. Bạn sẽ kết hợp với các case
của Enum, nhằm kiểm tra nó trong một số điều kiện nhất định. Xem qua ví dụ code tiếp nhóe!
enum State { case initial case active case done } var state = State.active guard case state = State.initial else { // Handle unexpected state } // Continue execution
Với ví dụ trên, nếu state
khác với .initial
thì các đoạn code ở dưới sẽ được thực thi. Bạn chỉ cần thực hiện câu lệnh guard case
thay vì phải switch ... case
nhóe. Cũng khá là tiện lợi phải không nào!
Tạm kết
Qua bài viết trên, bạn sẽ áp dụng được guard
trong các trường hợp throw errors, unwrap optionals, verify … hay kiểm tra các API … Khi bạn hiểu được ý nghĩa của mỗi trường hợp thì logic của bạn sẽ hiệu quả hơn, thay vì khô khan với if
nhóe!
Okay! Tới đây, mình xin kết thúc bài viết về Guard keyword trong iOS . Nếu có gì thắc mắc hay góp ý cho mình thì bạn có thể để lại bình luận hoặc gởi email theo trang Contact.
- Nguồn tham khảo tại đây!
Cảm ơn bạn đã đọc bài viết này!
Related Posts:
Written by chuotfx
Hãy ngồi xuống, uống miếng bánh và ăn miếng trà. Chúng ta cùng nhau đàm đạo về đời, về code nhóe!
Leave a Reply Cancel reply
Fan page
Tags
Recent Posts
- Charles Proxy – Phần 1 : Giới thiệu, cài đặt và cấu hình
- Complete Concurrency với Swift 6
- 300 Bài code thiếu nhi bằng Python – Ebook
- Builder Pattern trong 10 phút
- Observer Pattern trong 10 phút
- Memento Pattern trong 10 phút
- Strategy Pattern trong 10 phút
- Automatic Reference Counting (ARC) trong 10 phút
- Autoresizing Masks trong 10 phút
- Regular Expression (Regex) trong Swift
You may also like:
Archives
- September 2024 (1)
- July 2024 (1)
- June 2024 (1)
- May 2024 (4)
- April 2024 (2)
- March 2024 (5)
- January 2024 (4)
- February 2023 (1)
- January 2023 (2)
- November 2022 (2)
- October 2022 (1)
- September 2022 (5)
- August 2022 (6)
- July 2022 (7)
- June 2022 (8)
- May 2022 (5)
- April 2022 (1)
- March 2022 (3)
- February 2022 (5)
- January 2022 (4)
- December 2021 (6)
- November 2021 (8)
- October 2021 (8)
- September 2021 (8)
- August 2021 (8)
- July 2021 (9)
- June 2021 (8)
- May 2021 (7)
- April 2021 (11)
- March 2021 (12)
- February 2021 (3)
- January 2021 (3)
- December 2020 (3)
- November 2020 (9)
- October 2020 (7)
- September 2020 (17)
- August 2020 (1)
- July 2020 (3)
- June 2020 (1)
- May 2020 (2)
- April 2020 (3)
- March 2020 (20)
- February 2020 (5)
- January 2020 (2)
- December 2019 (12)
- November 2019 (12)
- October 2019 (19)
- September 2019 (17)
- August 2019 (10)