Natasha Murashev là một cựu nhân viên FBI, một nữ lập trình viên rất nổi tiếng trong cộng đồng lập trình nói chung và iOS nói riêng. Cô cũng là thành viên của trang web NSHipster và là chủ nhân của blog Natasha The Robot, bắt đầu từ hôm nay, Techmaster sẽ dịch các bài blog hàng ngày của Natasha trên trang này để các bạn dễ dàng tham khảo và nghiên cứu hơn.
Gần đây có một thứ khiến tôi để ý trong code của mình đó là tôi thường sử dụng guard và if. Thực tế là mỗi tôi hay thay thế if bằng guard mỗi khi có thể.
Nhưng đó chính là vấn đề, có một sự khác biệt giữa guard và if và chúng ta cần phải cân nhắc sử dụng cái nào cho hợp lý. Đầu tiên đó là guard nên được dùng khi bạn muốn giá trị chắc chắn được sử dụng trong function để thực thi.
Ví dụ trong ứng dụng try! Swift app, ở hình bên dưới, khi chúng ta muốn hiển thị một presentation session type, thì tiêu đề của presentation chính là tiêu đề của session.
Tuy nhiên, không phải session nào cũng có bài presentation, do vậy đối tượng presentation là kiểu optional, nhưng với session type, đó là một đối tượng được xác định là sẽ luôn tồn tại, do vậy đây là case thích hợp để sử dụng guard.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | @objc public enum SessionType: Int { case workshop case meetup case breakfast case announcement case talk case lightningTalk case sponsoredDemo case coffeeBreak case lunch case officeHours case party } public class Session: Object { // this is optional because not all sessions have presentations // e.g. no presentation during breakfast open dynamic var presentation: Presentation? // other properties here /** The main name of this session */ public var formattedTitle: String { switch self.type { case .talk, .lightningTalk: // for the talk / lighting talk session type // we expect the presentation to be there // if it's not there, it's a fail, so `guard` is used guard let presentation = presentation else { return defaultTitle } return presentation.localizedTitle // other cases continued... } } |
Talk title phải luôn có giá trị để hiển thị. Nếu không thì app sẽ crash. Đó là lý do vì sao chúng ta sử dụng guard để "bảo vệ" app trong trường hợp này.
Ở một trường hợp khác. Coffee Break session có thể có nhà tài trợ, trong case này, tiêu đề của coffee break sẽ kèm theo cả tê ncuar nhà tài trợ. Logic sẽ là, nếu có nhà tài trợ, chúng ta sẽ thêm tên nhà tài trợ vào khi hiển thị, còn không thì thôi. Ở đây, if sẽ là phương án tối ưu hơn.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public class Session: Object { /** A sponsor, if any, responsible for this session. */ open dynamic var sponsor: Sponsor? /** The main name of this session */ public var formattedTitle: String { switch self.type { case .coffeeBreak: // some sessions are sponsored, some aren't // it's not a fail if there is no sponsor // so `if` is used if let sponsor = sponsor { return "Coffee Break, by \(sponsor.name)".localized() } return "Coffee Break".localized() // other cases continued... } } |
Tổng kết lại thì:
Giống như câu lệnh if, guard thực thi các câu lệnh dựa trên giá trị Boolean, nhưng ngược với if, guard chỉ thực thi khi điều kiện không thỏa mãn. Thay vì crash app, bạn sẽ "nhẹ nhàng" thoát ra khỏi khối lệnh đó và thực thi các khối lệnh tiếp theo. Đúng như định nghĩa, guard là một tấm khiên bảo hộ cho app của bạn vậy.
Bình luận