Bảo vệ có thể cải thiện rõ ràng
Khi bạn sử dụng bảo vệ, bạn có một kỳ vọng cao hơn nhiều để người bảo vệ thành công và điều quan trọng là nếu nó không thành công, thì bạn chỉ muốn thoát khỏi phạm vi sớm . Giống như bạn bảo vệ để xem nếu một tập tin / hình ảnh tồn tại, nếu một mảng làEmpty hay không.
func icon() -> UIImage {
guard let image = UIImage(named: "Photo") else {
return UIImage(named: "Default")! //This is your fallback
}
return image //-----------------you're always expecting/hoping this to happen
}
Nếu bạn viết mã ở trên với if-hãy để nó truyền đạt cho nhà phát triển đọc rằng nó nhiều hơn 50-50. Nhưng nếu bạn sử dụng bảo vệ, bạn thêm sự rõ ràng vào mã của mình và nó ngụ ý rằng tôi hy vọng điều này sẽ hoạt động 95% thời gian ... nếu nó thất bại, tôi không biết tại sao nó lại xảy ra; điều đó rất khó xảy ra ... nhưng sau đó chỉ sử dụng hình ảnh mặc định này hoặc có lẽ chỉ cần xác nhận bằng một thông điệp có ý nghĩa mô tả những gì đã sai!
Tránh guard
s khi chúng tạo ra tác dụng phụ, các vệ sĩ sẽ được sử dụng như một dòng chảy tự nhiên . Tránh bảo vệ khi else
mệnh đề giới thiệu tác dụng phụ. Bảo vệ thiết lập các điều kiện cần thiết để mã thực thi đúng, cung cấp thoát sớm
Khi bạn thực hiện tính toán đáng kể trong nhánh tích cực, hãy cấu trúc lại từ if
một guard
câu lệnh và trả về giá trị dự phòng trong else
mệnh đề
Từ: Cuốn sách Phong cách Swift của Erica Sadun
Ngoài ra, là kết quả của các đề xuất và mã sạch ở trên, nhiều khả năng bạn sẽ muốn / cần thêm các xác nhận vào các tuyên bố bảo vệ thất bại , nó chỉ cải thiện khả năng đọc và làm rõ cho các nhà phát triển khác những gì bạn đang mong đợi.
guard let image = UIImage(named: selectedImageName) else { // YESSSSSS
assertionFailure("Missing \(selectedImageName) asset")
return
}
guard let image = UIImage(named: selectedImageName) else { // NOOOOOOO
return
}
Từ: Cuốn sách Phong cách Swift của Erica Sadun + một số sửa đổi
(bạn sẽ không sử dụng các xác nhận / điều kiện tiên quyết cho if-let
s. Nó dường như không đúng)
Sử dụng vệ sĩ cũng giúp bạn cải thiện sự rõ ràng bằng cách tránh kim tự tháp diệt vong. Xem câu trả lời của Nitin .
Bảo vệ tạo ra một biến mới
Có một sự khác biệt quan trọng mà tôi tin rằng không ai giải thích rõ.
Cả hai guard let
và if let
Unwrap biến tuy nhiên
Với guard let
bạn đang tạo một biến mới sẽ tồn tại bên ngoàielse
câu lệnh.
Với việc if let
bạn không tạo bất kỳ biến mới nào sau câu lệnh khác, bạn chỉ nhập khối mã nếu tùy chọn không phải là không. Biến mới được tạo chỉ tồn tại bên trong khối mã không sau!
guard let:
func someFunc(blog: String?) {
guard let blogName = blog else {
print("some ErrorMessage")
print(blogName) // will create an error Because blogName isn't defined yet
return
}
print(blogName) // You can access it here ie AFTER the guard statement!!
//And if I decided to do 'another' guard let with the same name ie 'blogName' then I would create an error!
guard let blogName = blog else { // errorLine: Definition Conflicts with previous value.
print(" Some errorMessage")
return
}
print(blogName)
}
if-let:
func someFunc(blog: String?) {
if let blogName1 = blog {
print(blogName1) // You can only access it inside the code block. Outside code block it doesn't exist!
}
if let blogName1 = blog { // No Error at this line! Because blogName only exists inside the code block ie {}
print(blogName1)
}
}
Để biết thêm thông tin về if let
hãy xem: Tại sao việc khai báo lại ràng buộc tùy chọn không tạo ra lỗi
Bảo vệ yêu cầu thoát khỏi phạm vi
(Cũng được đề cập trong câu trả lời của Rob Napier):
Bạn PHẢI đã guard
xác định bên trong một func. Mục đích chính của nó là hủy bỏ phạm vi / trả lại / thoát, nếu một điều kiện không được đáp ứng:
var str : String?
guard let blogName1 = str else {
print("some error")
return // Error: Return invalid outside of a func
}
print (blogName1)
Đối với if let
bạn không cần phải có nó trong bất kỳ func:
var str : String?
if let blogName1 = str {
print(blogName1) // You don't get any errors!
}
guard
đấu với if
Nó đáng chú ý là nó thích hợp hơn để xem câu hỏi này như guard let
vs if let
và guard
vs if
.
Một độc lập if
không làm bất kỳ điều gì, cũng không độc lập guard
. Xem ví dụ dưới đây. Nó không thoát sớm nếu giá trị là nil
. KHÔNG có giá trị tùy chọn. Nó chỉ thoát sớm nếu một điều kiện không được đáp ứng.
let array = ["a", "b", "c"]
func subscript(at index: Int) -> String?{
guard index > 0, index < array.count else { return nil} // exit early with bad index
return array[index]
}
if let
khinon-nil
trường hợp hợp lệ. Sử dụngguard
khinil
trường hợp đại diện cho một số loại lỗi.