What’s new in Swift 5.3
Multiple Trailing Closures
Since its inception, Swift has supported trailing closure syntax: a bit of syntactic sugar that lets you “pop” the final argument to a function out of the parentheses when it’s a closure
With Swift 5.3 it extends trailing closure syntax to allow additional labeled closures to follow the initial unlabeled closure.
- The first trailing closure drops its argument label (like today).
- Subsequent trailing closures require argument labels.
Multi Pattern Catch Clauses
Earlier multiple error handling in do-catch
statements required us to use eitherswitch
statement or if-else
conditions in a single catch
clause in order to handle various error cases or multiple catch statements. With Swift 5.3 we can handle multiple error cases in one catch
block as a comma-separated list, the catch statements now have full power of Switch cases.
Support of a multi-pattern catch clause allows much more clearer and concise code.
Synthesized Comparable
conformance for enum
types
Enumeration types which opt-in to a synthesized Comparable
conformance would compare according to case declaration order, with later cases comparing greater than earlier cases. Only enum
types with no associated values and enum
types with only Comparable
associated values would be eligible for synthesized conformances
- No
enum
types with raw values would qualify. - A conformance will not be synthesized if a type is ineligible or already provides an explicit
<
implementation.
Enum cases as protocol witnesses
Swift 5.3 lifted the existing restriction, which is that enum cases cannot participate in protocol witness matching.
The compiler allows a static protocol requirement to be witnessed by an enum case, under the following rules:
- A static, get-only protocol requirement having an enum type or
Self
type can be witnessed by an enum case with no associated values. - A static function requirement with arguments and returning an enum type or
Self
type can be witnessed by an enum case with associated values having the same argument list as the function's.
Refine didSet Semantics
Swift 5.3 Introduces two changes to didSet
semantics -
- If a
didSet
observer does not reference theoldValue
in its body, then the call to fetch theoldValue
will be skipped. We refer to this as a "simple" didSet. - If we have a “simple”
didSet
and nowillSet
, then we could allow modifications to happen in-place.
The property’s getter is no longer called if we do not refer to the oldValue
inside the body of the didSet.
This applies to a didSet
on an overridden property as well - the call to the superclass getter will be skipped if the oldValue
is not referenced in the body of the overridden property's didSet
.
Increase availability of implicit self
in @escaping
closures when reference cycles are unlikely to occur
In order to prevent users from inadvertently creating retain cycles, the Swift compiler today requires all uses of self
in escaping closures to be explicit. Attempting to reference a member x
of self
without the self
keyword gives the error:
error: reference to property 'x' in closure requires explicit 'self.' to make capture semantics explicit
Swift 5.3 allows the use of implicit self
when it appears in the closure's capture list.
Second, if self
is a value type, we will not require any explicit usage of self
(at the call/use site or in the capture list), so that if self
were a struct
or enum
then the above could be written as simply:
Float16
Add Float16
to the standard library.
References