Guard

Guard cũng gần giống như “if let” (optionals binding), nó cũng được sử dụng để xử lý các object dạng Optionals, cũng check các điều kiện khác “nil” thì cho phép thực hiện các logic tiếp theo… Nhưng Guard còn được gọi với tên gọi khác là “Early Exit”, vậy Guard khác “if let” (Optional binding) ở điểm nào?

Hãy xem xét ví dụ sau:

Raw: https://gist.github.com/RioV/f551c21f3c2c16946f2bdd338c3fd24f

Ví dụ trên là sự so sánh giữa việc sử dụng Optional Binding và Guard để xử lý việc check object có thoả mãn điều kiện là khác “nil” hay không.

Với Optional Binding thì ta tập trung xử lý trường hợp có value trước. Còn với Guard thì ta ưu tiên xử lý trường hợp không có value trước. Hai khái niệm trên cùng xử lý việc tương tự nhau, nhưng tuỳ hoàn cảnh cụ thể mà ta dùng Optional binding hay Guard cho phù hợp.

Tất nhiên là Guard còn được sử dụng để check hàng loạt các điều kiện khác nhau (không nhất thiết chỉ là check nil) xem các điều kiện có cùng thoả mãn hay không.

Ví dụ:

let name : String? = "Swift"
let version : Int = 3
let owner : String = "Apple"
func checkMultiCondition(name : String?, version : Int, owner : String) {
guard let name = name, version > 2, owner == "Apple" else {
print("Input parameters not match!!!")
return
}
print(name)
print(version)
print(owner)
}

Và dùng Guard để check các điều kiện tuần tự thì…tuyệt vời ông mặt giời luôn. (search thêm về Happy-Path Programming)

struct Student {
let name: String?
let age: Int?
let gender: String?
}
let student = Student(name: "Rio", age: 27, gender: "Male")
func validateStudentInfo (_ student: Student) -> String {
// We do NOT need to using student name, just want to check if
// student name have value, so using underscore here
if let _ = student.name {
if let _ = student.age {
if let _ = student.gender {
return "OK"
} else {
return "Gender not valid"
}
} else {
return "Age not valid"
}
} else {
return "Name not valid"
}
}
func validateStudentInfoWithGuard (_ student: Student) -> String {
guard let _ = student.name else {
return "Name not valid"
}
guard let _ = student.age else {
return "Age not valid"
}
guard let _ = student.gender else {
return "Gender not valid"
}
return "OK"
}
validateStudentInfo(student)
validateStudentInfoWithGuard(student)

Như đoạn code sample trên thì việc sử dụng Guard để check các điều kiện tuần tự nhau rất đơn giản và dễ đọc. Còn nếu sử dụng Optional Binding lồng nhau để check thì source code trông rất tệ và khó đọc. Hãy cân nhắc khi sử dụng 😉

Có một điều cần chú ý là, với Guard statement thì trong trường hợp “else”, ta bắt buộc phải return ;). Và sử dụng Guard một cách hợp lý sẽ làm source code dễ đọc hơn, dễ maintain hơn.

Nil Coalescing

Còn một cách khác để unwrap một object Optionals là sử dụng “nil coalescing”, trong các ngôn ngữ khác thì quen thuộc với cái tên “Null Coalescing” https://en.wikipedia.org/wiki/Null_coalescing_operator

Dùng “Nil Coalescing” khi mà bạn muốn có giá trị default nào đó cho Optional object, trong trường hợp nó bị nil, như dưới đây:

Trong ví dụ này ta thấy rằng trường hợp biến “name” bị nil thì lập tức nó được gán value là “No Name”

Chú ý rằng chỉ sử dụng “Nil Coalescing” với các Object optionals thôi nhé, nếu dùng cho object non-optionals thì compiler sẽ báo lỗi như dưới:

Nó dụ dỗ xoá nil coalescing đi luôn

Have Fun

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.