Swift

What’s New in Swift 4.2?

The second update release to Swift of 2018, Swift 4.2 introduces some great improvements to the language. Read this post to learn how they can help you write even better code.

Included in this version’s list of improvements:

  • SE-0194: Adds the CaseIterable protocol to automatically generate an array of all the possible enum cases.
  • SE-0195: Dynamic member lookup syntactical sugar.
  • SE-0196: New compiler directives #warning and #error.
  • SE-0197: New removeAll(where:) method to perform an optimized in-place filter for collections.
  • SE-0199: New toggle() method to easily toggle/flip boolean values.
  • SE-0202: New native random number generator.
  • SE-0206: New Hasher type to improve and simplify conformance to the Hashable protocol.
  • SE-0207: New allSatisfy() method to verify all elements in a sequence pass a condition. 
  • SE-0143: Conditional conformance improvements.

Enum Case Iteration

First up, Swift 4.2 introduces a new protocol for enums. If you make your enums conform to the CaseIterable protocol, you will be able to iterate through your list of enums in an array-like fashion, listing out all the possible cases. For example, take the following enum:

You can iterate through this enum list like an iterable, using the new allCases property, as follows:

Dynamic Member Lookup 

A new attribute, @dynamicMemberLookup, has been added to allow the Swift compiler to utilize a subscript method when accessing properties so that you can provide dot syntax for arbitrary names, which are then resolved at runtime. This takes a leaf out of Python’s book of conventions. When defining a subscript, you pass in a dynamicMember along with a list of properties that you will return, as follows:

This example illustrates receiving a dynamic member as a string and returning a string, whilst looking up the member name in the dictionary. The following implementation illustrates how this works:

Instantiating the class, the first two properties are dynamically discoverable and will return the default value of the member in a type-safe String at runtime. The last property (gender) does not exist in the class and would return nothing back, since we used an empty string as the default when looking up return values. You are not restricted to returning Strings—you can, in fact, return anything from a dynamic member lookup, including closures. 

New Compiler Warning and Error Directives

This new feature is a blast from the past for many who came from an Objective-C background, as the consortium introduces (or re-introduces) compiler directives for Swift to flag issues in your code. The two directives are #warning and #error

The #warning directive helps developers mark a block of code that has issues so these will show up as a warning in Xcode. The #error directive, however, will force a compile-time error and is useful if, for instance, you want to force the developer to look at your code and complete the block of code, e.g. by adding his or her own API token or credentials in lieu of the placeholder. The following example illustrates the latter use case:

New Method to Perform In-Place Filter for Collections

Through the new removeAll(where:) method, developers can now perform in-place filtering on collections by passing a closure condition. Say you have an array of shirts, and want to remove a specific value, medium. You would have previously done something like:

With the addition of removeAll(where:), instead of filtering to remove, you can run a more memory-optimized operation that removes explicitly and in-place:

Easily Toggle or Flip Between Boolean Values

A simple but welcome improvement, SE-0199 introduces boolean toggling through the toggle() method. In a familiar pattern, you would have something like the following:

With the addition of this new method, you could write instead:

New Native Random Number Generator

Surprisingly, until Swift 4.1, the language lacked a native random number generator, forcing developers instead to rely on arc4random_uniform() to return a uniformly distributed random number. Now, you can simply call the random() method along with a specific range to work with:

This method is supported on other numerical types beyond Int, including Float, Double, CGFloat, Bool, and Array.

The Bool lets you get back a random true or false response. This proposal also called for two array-related methods: the shuffled() method, which lets you randomize an array order, and randomElement(), which returns a random element from an array. 

Here's an example of how you would use the new shuffled() method:

We can also use the randomElement() method to improve the code we had earlier to get a random shirt size:

Improvements to Hashable Protocol Conformance

Swift has improved how your custom object types conform to the Hashable protocol—making it faster, simpler, and more secure—through a new Hasher struct. Previously, whenever you created dictionaries or sets, you would have a type that conformed to Hashable, which gives you an optimized hash for free. However, when implementing your own type that conformed to Hashable, you needed to create your own algorithm to calculate the hashValue by hand. 

Swift 4.1 improved this significantly by inferring what could be used to uniquely identify the object:

However, when you had to work with a more complex object type, you still needed to implement an algorithm to return a unique hashValue

Swift 4.2 introduces the new Hasher struct, which can calculate a unique hash value for you:

To implement the new Hasher struct, you create a Hasher instance and provide the custom types you want to combine. The Hasher instance will create and return a unique hash. 

Ensure All Elements in a Sequence Satisfy a Condition

The final feature accepted into Swift 4.2 is SE-0207, which adds a new method, allSatisfy(), to verify whether all items in a sequence conform to a certain sequence condition. While you were already able to use the contains method to verify whether an element in a collection satisfied a condition, the allSatisfy method returns a boolean based on whether the entire set of elements satisfies a condition.

The following implementation of allSatisfy asserts whether the entire sequence of shirtOrderPrices is satisfied by the condition of being over $20:

Conclusion

Swift remains a growing language, with new features being added and debated all the time. You can track the most up-to-date list of proposals, and the acceptance status of each one, by visiting Swift Evolution.

Powered by WPeMatico

Leave a Comment

Scroll to Top