📜 ⬆️ ⬇️

What's new in Swift 4.1


This post is a free translation of the article What's new in Swift 4.1 by Paul Hudson


Swift 4.1 is the first minor release of Swift 4, which brought with it some useful features, such as automatic use of Equatable and Hashable, conditional matches, etc.


Be sure to set yourself at least Xcode 9.3 , then create a new playground. Let's look at the new features of this version ...


Equatable and Hashable


Equatable protocol allows Equatable to compare one entity with another. When we say 5 == 5 , Swift understands what this means because Int complies with the Equatable protocol, which means it implements a function that describes what " == " means for entities of type Int .

Implementing Equatable in your own types (structures, enumerations) allows you to work with them as well as with strings, arrays, numbers, etc. And it will be good if your structures comply with the Equatable protocol in order to better fit the general concept of types that are passed by value.


However, the implementation of Equatable may not be too elegant. For example, we have the following structure:


 struct Person { var firstName: String var middleName: String var age: Int var city: String } 

And if you have two entities of type Person and you want to compare them, you need to compare all four properties, like this:


 struct Person: Equatable { var firstName: String var lastName: String var age: Int var city: String static func ==(lhs: Person, rhs: Person) -> Bool { return lhs.firstName == rhs.firstName && lhs.lastName == rhs.lastName && lhs.age == rhs.age && lhs.city == rhs.city } } 

It's hard to even read , not like writing .


Fortunately, in Swift 4.1 it is possible to automatically match for Equatable , the method == will be generated automatically and will compare all the properties of the first entity with all the properties of the second, as described above. All you need to do is add Equatable to your type, and Swift does the rest.


Naturally, you can implement your own version of the method == . For example, if your type has an id property that uniquely identifies an entity, you could write == to compare only this property, instead of Swift doing the extra work.


Similar to Equatable , Swift 4.1 also introduced support for Hashable . Now hashValue can be automatically generated to match this protocol. Hashable usually annoying, because you need to return a unique (more or less unique) hash for each entity. This is important because it allows you to use your entities as keys for dictionaries, or allows you to store entities in sets.


Previously, it was necessary to write something like this:


 var hashValue: Int { return firstName.hashValue ^ lastName.hashValue &* 16777619 } 

Given this, you now hardly need to write your own implementation of hashValue in Swift 4.1, but if you still need it, you can do it (similarly == in Equatable ).


Note: Add, if necessary, these protocols to your types, and do not forget that all fields of your types must also correspond to them.


More information can be found here: Swift Evolution proposal SE-0185 .


Conditional matches


Swift Evolution proposal SE-0143 offered conditional correspondences, and they are now in Swift 4.1. This is a powerful feature that will be useful to very many. With her now earn things that have not worked before. For example, in Swift 4.0, such code will not compile:


 var left: [String?] = ["Andrew", "Lizzie", "Sophie"] var right: [String?] = ["Charlotte", "Paul", "John"] left == right 

That's because String and [String] are Equatable , but [String?] Is not. A conditional match means that the type will conform to the protocol as long as a certain condition is satisfied. This means that if the elements of the array match Equatable - the whole array corresponds to Equatable .


Conditional matching is common to the Codable protocol, and this will make some things more secure. Take a look at this code:


 struct Person { var name = "Taylor" } var people = [Person()] var encoder = JSONEncoder() try encoder.encode(people) 

We have an array of one element of type Person , and we are trying to convert this array to JSON. Such code is quietly compiled in Swift 4.0, but in runtime you will get an error, because Person does not comply with the Codable protocol. Swift 4.1 solves this problem: Optional , Array , Dictionary and Set now conform to the Codable protocol only if their contents conform to this protocol, therefore in Swift 4.1 such code simply does not compile.


Conditional matching is one of the features that makes life easier for most people, even those who do not write a lot of code.


flatMap is now (almost) compactMap


flatMap() is useful for many things in Swift 4.0, but its main feature is to convert entities into collections, removing nil from the result.


In Swift Evolution proposal, SE-0187 was proposed to change this, and in Swift 4.1, flatMap() renamed to compactMap() to more clearly convey its meaning.


For example:


 let array = ["1", "2", "Fish"] let numbers = array.compactMap { Int($0) } 

This will create an array with Int elements, which will contain the numbers 1 and 2, because "Fish" when converted to Int will return nil and will be ignored.


We are waiting for Swift 5.0


Implementing conditional compliance contributes to stability, and automatic support for Equatable and Hashable definitely simplify the lives of developers.


Other proposals are now either under review or under development, including: SE-0192: Non-Exhaustive Enums , SE-0194: Derived Collection of Enum Cases and SE-0195: Dynamic Member Lookup .


It is equally important that this year Apple will hopefully release ABI stabilization for Swift, and it will be great . We are waiting, sir.


')

Source: https://habr.com/ru/post/352514/


All Articles