Optional trong Swift

Giới thiệu

Chắc hẳn các bạn đã được nghe nhiều từ những vận chuyển tận nhàer Swift nói về sự tuyệt vời của Optional, một trong những đặc điểm cơ bản của ngôn ngữ lập trình Swift. Optional là một khái niệm mới trong ngôn ngữ lập trình Swift. Với việc dùng optional, ngôn ngữ Swift được Apple giới thiệu là ngôn ngữ “an toàn” hơn so với ngôn ngữ Objective-C trước đó. Nếu bạn đã đã có lần bị khách phàn nàn về việc app crash, chỉ vì vận chuyển tận nhàe của bạn cho chèn giá trị nil vào một Dictionary, vào web vào 1 object đã giải phóng, hay một đoạn text ở UILabel hiển thị nil, Optional sẽ giúp đỡ bạn trong những hoàn cảnh này. Optional sinh ra để xử lý với các hoàn cảnh object ko có giá trị.

Khai báo Optional

Khai báo Integer Optional

var perhapsInt: Int? 

Khai báo String Optional

var perhapsStr: String? 

Khai báo Optional

var variableName: ValueType? 

ValueType ở đây có thể là String, Integer, Float, hay 1 custom object …
Trong Swift, khi khởi tạo các biến, các biến này mặc định sẽ được khởi tạo dưới dạng non-optional, tức là phải được gán giá trị mà không được để nil. Nếu ta gán giá trị nil cho các biến non-optional này, trình biên dịch sẽ thông tin lỗi.
Ví dụ:

var str: String //compile error  

Biến str là kiểu String, kiểu non-optional nhưng ko gán giá trị mặc định nên Xvận chuyển tận nhàe sẽ báo lỗi

var str: String = “Hello Swift” // OK str = nil // biên dịch lỗi  

Như trên biến str có kiểu String, đây là kiểu non-optional nên ta phải gán giá trị mặc định cho nó là "Hello Swift", dòng bên dưới ta gán str = nil trong khi str là kiểu non-optional nên Xvận chuyển tận nhàe sẽ báo lỗi trong hoàn cảnh này.
Khai báo dạng optional:

var str: String? = “Hello Swift” // OK str = nil // OK  

Forced Unwrapping

If you defined a variable as optional, then to get the value from this variable, you will have to unwrap it. This just means putting an exclamation mark at the end of the variable.

Let’s take a simple example −
Nếu được hiểu một biến kiểu optional, tiếp theo nếu ta muốn lấy giá trị từ biến này, ta phải unwrap nó. Ở đây ta sẽ có 2 khái niệm là wrap và unwrap, ta xem ví dụ sau:

var msg: String? = "Hello Swift" 

Ở đây biến msg có kiểu data là String?, Kiểu data String thì ta đều đã biết, vậy còn String? nó là 1 wrap của kiểu String, nó là kiểu String + nil, do đó 2 kiểu String và String? là khác nhau, muốn lấy giá trị của msg ta phải unwrap nó tức là lấy kiểu String của nó.
Chạy đoạn vận chuyển tận nhàe sau:
import Cocoa

var myString:String?  myString = "Hello, Swift!"  if myString != nil {    println(myString) }else {    println("myString has nil value") } 

Ta sẽ nhận được output như sau:

Optional("Hello, Swift!") 

giờ đây ta sẽ force unwrap để lấy được giá trị đúng của myString

import Cocoa  var myString:String?  myString = "Hello, Swift!"  if myString != nil {    println( myString! ) }else {    println("myString has nil value") } 

Kết quả:

Hello, Swift! 

Vậy ta force unwrap bằng cách thêm ! sau biến cần unwrap
mặc dù vậy việc force unwrap là việc nên tránh, vì hoàn cảnh nếu biến force unwrap đó nil thì sẽ gây crash app

Automatic Unwrapping

Ví dụ:

import Cocoa  var myString:String!  myString = "Hello, Swift!"  if myString != nil {    println(myString) }else {    println("myString has nil value") } 

Ở đây biến myString được khai báo kiểu String!, khi ta gọi hàm println(myString) thì biến myString này đã tự động unwrap thành kiểu String

Optional Binding

dùng optional binding để check xem biến optional có giá trị hay ko, để có những xử lý tương ứng tránh bị crash app

var myString:String?  myString = "Hello, Swift!"  if let yourString = myString {    println("Your string has - \(yourString)") }else {    println("Your string does not have a value") } 

Kết quả:

Your string has - Hello, Swift! 

Optional Chaining

Ví dụ sau:

class Stock = {      var vận chuyển tận nhàe: Sring?      var price: Double?  }  func findStockvận chuyển tận nhàe(company:String) -> Stock? {      if(company == “Apple”) {          let appl: Stock = Stock()          appl.vận chuyển tận nhàe = “APPL”          appl.price = 90.32          return appl      }else if (company == “Google”) {          let goog: Stock = Stock()          goog.vận chuyển tận nhàe = “GOOG”          goog.price = 90.32          return appl      }      return nil }  if let stock = findStockvận chuyển tận nhàe(“Apple”) {      if let sharePrice = stock.price {          let totalPrice = sharePrice * 100          println(totalPrice)      }  } 

Ta có thể dùng optional chaining làm cho vận chuyển tận nhàe ngắn hơn như sau:

if let sharePrice = findStockvận chuyển tận nhàe(“Apple”)?.price {      let totalPrice = sharePrice * 100      println(totalPrice)  } 

Kết luận

Trong bài viết này tôi đã giới thiệu đến các bạn khái niệm optional, một khái niệm mới của Swift giúp đỡ cho vận chuyển tận nhàer cam kết vận chuyển tận nhàe của mình an toàn hơn khi phải check nil với các biến trước khi làm thao tác nào đó trên biến đó, điều này sẽ giúp đỡ giảm thiểu tình trạng crash app.
Để hiểu thêm các bạn có thể tham khảo thêm ở các tài liệu sau:
https://lập trình viêneloper.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/TheBasics.html
http://www.appvận chuyển tận nhàa.com/beginners-guide-optionals-swift/
https://www.tutorialspoint.com/swift/swift_optionals.htm

Nguồn viblo.asia