Swift — Những điểm mới ở Swift 5 (1)

Hoàng Minh Nhật
Living is Sharing
Published in
4 min readMar 29, 2019

--

25/3/2019, Swift 5 đã chính thức ra mắt với nhiều tính năng mới, bài viết này sẽ liệt kê một vài tính năng mà có thể hay sử dụng nhất.

Raw stringsA standard Result typeDynamically callable typesHandling future enum casesFlattening nested optionals resulting from try?Transforming and unwrapping dictionary values with compactMapValues()

I. Raw strings

Ở Swift 4.2 về trước thì đối với những string mà chứa ký tự \ (backslash) hoặc “ (quote mark) thì ta phải thêm một ký tự backslash vào phía trước những ký tự đó thì Swift mới nhận dạng chúng dưới dạng string được. Ví dụ:

Sample strings in Swift 4.2

Tuy nhiên, ở Swift 5, điều đó đã trở nên đơn giản hơn với “Raw string”, để khai báo raw string, chỉ cần thêm ký tự # (hash symbol) vào trước và sau cách khai báo string cũ:

Sample raw string in Swift 5

Lưu ý:

  • Việc thêm giá trị của biến vào string (string interpolation) nếu dùng raw string thì có sự update như sau:
Raw string interpolation sample in Swift 5
  • Nếu muốn khai báo string có ký tự # (hash symbol) thì sử dụng ##””##
  • Nếu bạn là một người khá bựa và muốn khai báo raw string chứa cả cụm ký tự sau “## thì bạn có thể khai báo như dưới

// Bạn có thể thêm thoải mái ký tự # vào trước và sau của raw string

II. A standard Result type

Result type thì không phải là ý tưởng mới, rất nhiều developer đã tự implement Result type cho chính mình để xử lý các logic phức tạp như fetch data từ server, nó sẽ bao gồm xử lý các case network fail, các case server fail…

Dưới đây là ví dụ của cách fetch data từ server mà đa số developers vẫn đang dùng:

Với cách này, thì func `fetchDataFromServer` sẽ call closure `completion` khi fetch data thành công, và vì closure này trả về 2 tham số dạng Data? (optional) và String? nên không có gì đảm bảo rằng 2 tham số này không nil, do đó ta luôn phải check giá trị của chúng như ở trong func `fetchDataFromServer`.

Ví dụ về cách fetch data sử dụng Result type ở Swift 5:

Với cách làm sử dụng Result type thì func `fetchDataFromServer` có thể sử dụng switch case để xử lý các trường hợp success/failed, và chỉ có thể 1 case có thể xảy ra: nếu success thì không thể failed và ngược lại.

Đối với cách làm này thì ít nhất, source code cũng trở nên rất dễ đọc. Logic trở nên tường minh hơn.

Ứng dụng của Result có thể dùng xử lý những trường hợp như fetch data từ server, đọc content từ file, gửi tín hiệu và đợi response…

Readmore: https://github.com/apple/swift-evolution/blob/master/proposals/0235-add-result.md

III. Dynamically callable types

Dynamic member lookup

Trước khi đến với `Dynamically callable types` thì trước tiên ta nên quay lại với Swift 4.2 và làm quen với `Dynamic Member Lookup`

`Dynamic member lookup` có khả năng cung cấp cách truy cập vào thuộc tính (properties) của object bằng `dot syntax`, và những thuộc tính đấy cũng được xử lý lúc runtime. Hơi khó hiểu? Xem ví dụ dưới để hiểu dễ hơn.

Ở ví dụ này thì `Computer` là Struct có thể sử dụng dot syntax để truy xuất giá trị của các properties mà khi compile, những properties đó hoàn toàn chưa được define. Ở đây, đơn giản chỉ là những properties như brand/type/color sẽ được sử dụng như “key” của dictionary “values”, và sau đó giá trị của “key” sẽ được trả về nếu có.

Syntax yêu cầu: subscript(dynamicMember:)

Dynamically “callable” types

`Dynamically callable type` đơn giản giống như là mảnh ghép hoàn thiện của Dynamic member lookup.

Xem xét ví dụ sau:

Ở ví dụ trên, ta có 2 lines of code nhìn rất lạ là:

dynamicCal(1, 2, 3)

dynamicCal(minus: 9, plus: 2, 3)

Tại sao 1 object (instance của class) lại có thể “call” được? Đây chính là bởi vì thuộc tính @dynamicCallable đã làm cho `DynamicCalculator` trở thành “có thể gọi được”. Lúc này 2 đoạn code phía trên sẽ trở thành:

dynamicCal.dynamicallyCall(withArguments: [1, 2, 3])

dynamicCal.dynamicallyCall(withKeywordArguments: [“minus”: 9, “plus”: 2, “”: 3])

Ứng dụng của Dynamic member lookup và Dynamically callable types là gì?

-> Về cơ bản, nếu bạn là một iOS developer thì bạn không nên quá quan tâm về 2 khái niệm trên làm gì, vì nó khá là vô nghĩa. Tuy nhiên, nếu bạn là một developer sử dụng Swift như là ngôn ngữ phát triển web/server thì đây chính là khái niệm rất hay dành cho bạn:

Dynamic member lookup và Dynamically callable types chính là cách mà Swift tương tác với các scripting languages khác như JS hay Python một cách thuận tiện và vẫn giữ được syntax của Swift. Nhờ đó Swift có thể sử dụng những libs hoặc frameworks được viết bằng Python… một cách đơn giản. Ví dụ như thằng cu này chẳng hạn: https://www.tensorflow.org/swift

Hết phần 1.

--

--