Skip to main content

Có gì mới ở Swift 5.0?


Theo thông tin trên trang https://swift.org/, ngày 16/11/2018, Swift 5.0 đã có những thay đổi cuối cùng để chuẩn bị release. Có rất nhiều tính năng mới, thú vị và hữu ích sẽ xuất hiện trong phiên bản này. Vậy chúng ta hãy cùng nhau khám phá những tính năng đó là gì nhé!

1. Raw string

Thông thường, ở trong một String, những kí tự như \ " ... được trình biên dịch hiểu là các kí tự thoát (escapes characters) và kí tự chấm dứt chuỗi (string terminators). Tuy nhiên, với Raw String thì những kí tự này sẽ được coi là các kí tự bình thường. Để tạo Raw String, chúng ta chỉ cần đặt String đó vào trước và sau 1 hoặc nhiều dấu #. Ví dụ:
let sentence1 = #"He said: "I'm hungry"."#
let sentence2 = ###"He said: "I'm thirsty"."###
Khi đó, dấu " đứng trước từ I'm không còn được coi là kết thúc String nữa mà được trình biên dịch coi như 1 kí tự thông thường. Tương tự đối với dấu \:
let temp = #"iOS\Swift\5.0"#
Tuy nhiên điều này dẫn đến sự thay đổi khi bạn sử dụng chuỗi nội suy (string interpolation). Ví dụ:
let age = 22
let sentence = #"She is \#(age) years old."#
Khi đó bạn phải thêm dấu # nếu muốn dùng chuỗi nội suy. Như mình đã nói ở trên, có thể dùng nhiều kí tự # để tạo Raw String. Có thể bạn đang nghĩ rằng dùng 1 dấu # là được rồi cần gì phải nhiều. Tuy nhiên có 1 vài trường hợp khá đặt biệt bạn sẽ phải dùng tới nó. Ví dụ với chuỗi
"He said: "I'm hungry"#hesaid"
nếu dùng 1 dấu # thì sẽ là:
let sentence = #"He said: "I'm hungry"#hesaid"#
Bạn có thể thấy có kí tự "# trong chuỗi nên trình biên dịch sẽ hiểu đó là kí tự kết thúc của Raw String. Vậy nên ta phải dùng nhiều dấu # để tạo Raw String trong trường hợp này:
let sentence = ##"He said: "I'm hungry"#hesaid"##
Thêm 1 tính năng thú vị nữa của Raw String là đối với chuỗi nhiều dòng chỉ cần dùng #""""""#
let introduce = #"""
My name is Hung,
I'm 22 years old,
Nice to meet you.
"""#

2. Quản lý các enum cases trong tương lai

Trong Swift, khi sử dụng switch thì các case phải cover hết các trường hợp. Ví dụ:
enum State {
    case success
    case fail
    case timeout
}

func showMessage(state: State) {
    switch state {
    case .success:
        print("Success")
    case .fail:
        print("Failure")
    default:
        print("Something went wrong")
    }
}
Và sau này sinh ra thêm case pending trong State, khi đó function của chúng ta vẫn sẽ chỉ thông báo Something went wrong. Swift tất nhiên sẽ không thể thông báo lỗi cho chúng ta. Tuy nhiên với Swift 5.0 chúng ta hoàn toàn có thể quản lý được điều này. Chỉ cần thêm @unknown vào trước default, ta sẽ nhận được warning mỗi khi thêm 1 case mới:
func showMessage(state: State) {
    switch state {
    case .success:
        print("Success")
    case .fail:
        print("Failure")
    @unknown default:
        print("Something went wrong")
    }
}

3. Nested optionals resulting from try?

Kể từ Swift 5.0, cách mà try? hoạt động sẽ giống như cơ chế của optional chaining. Hãy xem thử ví dụ:
struct User {
    var id: Int
    
    init?(id: Int) {
        if id < 1 {
            return nil
        }
        self.id = id
    }
    
    func getMessages() throws -> String {
        // complicated code here
        return "No messages"
    }
}

let user = User(id: 1)
let messages = try? user?.getMessages()
Ta có thể thấy struct User có 1 hàm khởi tạo optional nên đối tượng user được khởi tạo ở trên là kiểu optional. Ta sử dụng optional chaining để gọi phương thức getMessages(). Tuy nhiên phương thức này có thể throws nên ta dùng try? để tiếp tục chuyển nó sang kiểu optional. Kết quả đối tượng messages là kiểu String?? - optional optional String. Tuy nhiên từ Swift 5.0, try? sẽ không wrap giá trị đã là optional nên messages sẽ chỉ là kiểu String?. Có thể thấy cách hoạt động này giống với optional chaining khi cho dù chúng ta có lồng bao nhiêu tầng optional đi nữa thì kết quả cuối cùng vẫn chỉ có 1 tầng optional.

4. Kiểm tra bội số

Swift 5.0 sẽ cung cấp thêm phương thức isMultiple(of:) của integer để kiểm tra bội số thay vì sử dụng % như trước
if number.isMultiple(of: 2) {
    print("Even")
} else {
    print("Odd")
}

5. Phương thức count với Sequence

Tiếp tục là một phương thức mới nữa là count(where:) , nó có thể áp dụng cho các kiểu conform giao thức Sequence. Cách hoạt động giống với filter()
let numbers = [1, 2, 3, 4, 5]
let count = numbers.count { $0.isMultiple(of: 2) }
Kết quả là nó sẽ đếm những phần tử thỏa mãn điều kiện trong closure.

6. Biến đổi các giá trị của Dictionary với compactMapValues()

Đối với mảng, phương thức compactMap() sẽ biến đổi giá trị, unwrap các kết quả, loại bỏ nil thì phương thức compactMapValues() trong Dictionary sẽ giữ nguyên các key và biến đổi các values.
let ages = [
    "Hung": "22",
    "Long": "23",
    "Dong": nil,
    "Son": "Not determine"
]
Chúng ta có thể dùng để lọc lấy các value là số nguyên như sau:
let age1 = ages.compactMapValues { Int($0) }
hoặc
let age2 = ages.compactMapValues (Int.init)
Còn nếu muốn lấy các value không nil thì cũng chỉ cần
let age3 = ages.compactMapValues { $0 }
Nguồn: https://www.hackingwithswift.com/articles/126/whats-new-in-swift-5-0

Comments

Popular posts from this blog

Swift GCD part 1: Thread safe singletons

Preview Singletons are entities, referenced to the same instance of a class from everywhere in your code. It doesn't matter if you like them or not, you will definitely meet them, so it's better to understand how they work. Constructing and handling a set of data doesn't seem to be a big challenge at first glance. The problems appear when you try to optimise the user experience with background work and your app starts acting weird. ??‍♂️ After decades of watching your display mostly with a blank face, you finally realize that your data isn't handled consistently by the manager because you're accessing it (running tasks on it) from multiple threads at the same time. So you really do have to deal with making your singletons thread safe. This article series is dedicated to thread handling using Swift. In the first part below you will get a comprehensive insight into som...

Kiến thức cơ bản về RxSwift

Bài viết với mong muốn cung cấp thông tin cơ bản về kiến trúc, các thuật ngữ được sử dụng phổ biến về RxSwift, giúp những lập trình viên lần đầu làm quen RxSwift sẽ trở nên dễ dàng hơn. Trong bài viết có sử dụng một số từ khóa tiếng Anh, mình xin phép sẽ giữ nguyên bản không sử dụng tiếng Việt vì có lẽ sẽ dễ hiểu hơn cho người đọc. Observable Sequences Mọi hoạt động trong RxSwift từ việc đăng ký và xử lý sự kiện đều thông qua một Observable Sequences Trong RxSwift , các kiểu dữ liệu như Arrays , Strings hoặc Dictionary sẽ được convert sang Observable Sequences . Ta có thể tạo ra "Observable Sequences" của bất kỳ kiểu đối tượng nào tuân theo Sequence Protocol của Swift Standard Library . let helloSequence = Observable.just( "Hello Rx" ) let fibonacciSequence = Observable. from ([ 0 , 1 , 1 , 2 , 3 , 5 , 8 ]) let dictSequence = Observable. from ([ 1 : "Hello" , 2 : "World" ]) Đăng ký nhận event từ ""Observable Se...

Thread safe singleton’s in Swift

What are singletons? — Singleton is design patterns which says that there should be only one instance of the class for the lifetime of the application. One the best example of Singleton is AppDelegate . How to write a singleton class ? class DefaultDict{ private var dict:[String:Any] = [:] public static let sharedManager = DefaultDict() private init(){ } public func set(value:Any,key:String){ dict[key] = value } public func object(key:String) -> Any?{ dict[key] } public func reset(){ dict.removeAll() } }   Testing singleton class under concurrent circumstances. We are going to write an example where we will set values in dict from various threads and even try to access some with different threads. When we do this we will encounter a crash. If you look closely it will be because of race condition and the crash will be on line set(value:Any,key:String) . class ViewController: UIViewController { ...