What's New in Swift 4.1


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


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


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


    Equatable and Hashable


    The protocol Equatableallows you to compare one entity with another. When we talk 5 == 5, Swift understands what this means because it Intconforms to the protocol Equatable, and therefore it implements a function that describes what “ ==" means for entities of the type Int.

    Implementation Equatablein 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 follow the protocol Equatablein order to better conform to the general concept of types that are passed by value.


    However, the implementation Equatablemay not be too elegant. For example, we have such a structure:


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

    And if you have two type entities Personand 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 to write .


    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 have to do is add Equatableto your type, and Swift will do the rest.


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


    Similarly Equatable, in Swift 4.1, support was also introduced Hashable. Now hashValuecan be generated automatically to comply with this protocol. Hashableusually 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, you had to write something like this:


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

    Given this, you are now unlikely to need to write your implementation hashValuein Swift 4.1, but if you still need it, you can do it (similarly ==to Equatable).


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


    You can find more information here: Swift Evolution proposal SE-0185 .


    Conditional Compliance


    The Swift Evolution proposal SE-0143 proposed conditional matches, and they are now in Swift 4.1. This is a powerful feature that will benefit many. Things that have not worked before will now work with her. 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

    All because Stringand [String]- are consistent Equatable, but [String?]- not. Conditional matching 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 entire array matches Equatable.


    Conditional matching extends to the protocol Codable, 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 type element Person, and we are trying to convert this array to JSON. Such code compiles quietly in Swift 4.0, but in runtime you get an error because it Persondoes not comply with the protocol Codable. Swift 4.1 solves this problem: Optional, Array, Dictionaryand Setis now consistent with the Protocol Codableonly if their content matches the protocol, so the Swift 4.1 this code simply will not compile.


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


    flatMap is now (almost) compactMap


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


    The Swift Evolution proposal SE-0187 suggested changing this, and in Swift 4.1 it was flatMap()renamed compactMap()to more clearly convey its meaning.


    For instance:


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

    This will create an array with elements of the type Intthat will contain the numbers 1 and 2, because "Fish" Intwill return niland will be ignored when converted to .


    Looking forward to Swift 5.0


    Implementation of conditional compliance contributes to stability, and automatic support Equatableand Hashablewill definitely make life easier for developers.


    Other offers are currently 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, we hope, will release ABI stabilization for Swift, and it will be great . We are waiting, sir.


    Also popular now: