What’s New in Swift 5.1?
Swift 5.1 is finally out! This article will take you through the advancements and changes the language has to offer in its latest version. By Cosmin Pupăză.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
What’s New in Swift 5.1?
25 mins
- Getting Started
- Language Improvements
- Opaque Result Types
- Implicit Returns From Single-Expression Functions
- Function Builders
- Property Wrappers
- Synthesizing Default Values for Initializers in Structures
- Self for Static Members
- Creating Uninitialized Arrays
- Diffing Ordered Collections
- Static and Class Subscripts
- Dynamic Member Lookup for Keypaths
- Keypaths for Tuples
- Equatable and Hashable Conformance for Weak and Unowned Properties
- Ambiguous Enumeration Cases
- Matching Optional Enumerations Against Non-optionals
- New Features for Strings
- Contiguous Strings
- Miscellaneous Bits and Pieces
- Converting Tuple Types
- Tuples with Duplicate Labels
- Overloading Functions With Any Parameters
- Type Aliases for Autoclosure Parameters
- Returning Self From Objective-C methods
- Stable ABI Libraries
- Where to Go From Here?
Good news: Swift 5.1 is now available in Xcode 11 beta! This release brings module stability and improves the language with important features. In this tutorial, you’ll learn about what’s new in Swift 5.1. You’ll need Xcode 11 beta to work with Swift 5.1, so go ahead and install it before getting started.
Getting Started
Swift 5.1 is source compatible with Swift 5. It’s also binary compatible with Swift 5 and future releases of Swift thanks to ABI stability.
Swift 5.1 adds module stability on top of ABI stability introduced in Swift 5. While ABI stability takes care of app compatibility at runtime, module stability enables library compatibility at compile time. This means you can use a third-party framework with any compiler version instead of only the one it was built with.
Each tutorial section contains Swift Evolution proposal numbers such as [SE-0001]. You can explore each change by clicking the linked tag of each proposal.
I recommend you follow the tutorial by trying out the new features in a playground. Start Xcode 11 and go to File ▸ New ▸ Playground. Choose iOS for the platform and Blank as its template. Name it and save it where you want. Time to get started!
Language Improvements
There are a number of language improvements in this release, including opaque result types, function builders, property wrappers and more.
Opaque Result Types
You may use protocols as return types for functions in Swift 5.
With your new Playground open, open the Project Navigator by navigating to View ▸ Navigators ▸ Show Project Navigator. Right-click on the Sources folder, select New File and name the file BlogPost. Replace the contents of the new file with the definition of a new protocol named BlogPost
.
public protocol BlogPost {
var title: String { get }
var author: String { get }
}
Right-click on the top level playground and select New Playground Page. Rename the new playground page Opaque Tutorials and paste this in it:
// 1
struct Tutorial: BlogPost {
let title: String
let author: String
}
// 2
func createBlogPost(title: String, author: String) -> BlogPost {
guard !title.isEmpty && !author.isEmpty else {
fatalError("No title and/or author assigned!")
}
return Tutorial(title: title, author: author)
}
// 3
let swift4Tutorial = createBlogPost(title: "What's new in Swift 4.2?",
author: "Cosmin Pupăză")
let swift5Tutorial = createBlogPost(title: "What's new in Swift 5?",
author: "Cosmin Pupăză")
Going over this step by step:
- Declare
title
andauthor
forTutorial
sinceTutorial
implementsBlogPost
. - Check if
title
andauthor
are valid and returnTutorial
fromcreateBlogPost(title:author:)
if the test succeeds. - Use
createBlogPost(title:author:)
to createswift4Tutorial
andswift5Tutorial
.
You can reuse the prototype and logic of createBlogPost(title:author:)
to create screencasts as well because screencasts are blog posts under the hood too.
Right-click on the top level playground and select New Playground Page. Rename the new playground page Opaque Screencasts and paste this in it:
struct Screencast: BlogPost {
let title: String
let author: String
}
func createBlogPost(title: String, author: String) -> BlogPost {
guard !title.isEmpty && !author.isEmpty else {
fatalError("No title and/or author assigned!")
}
return Screencast(title: title, author: author)
}
let swift4Screencast = createBlogPost(title: "What's new in Swift 4.2?",
author: "Josh Steele")
let swift5Screencast = createBlogPost(title: "What's new in Swift 5?",
author: "Josh Steele")
Screencast
implements BlogPost
, so you return Screencast
from createBlogPost(title:author:)
and use createBlogPost(title:author:)
to create swift4Screencast
and swift5Screencast
this time.
Navigate to BlogPost.swift in the Sources folder and make BlogPost
conform to Equatable
.
public protocol BlogPost: Equatable {
var title: String { get }
var author: String { get }
}
At this point, you’ll get an error that BlogPost
can only be used as a generic constraint. This is because Equatable
has an associated type called Self
. Protocols with associated types are not types, even though they look like types. Instead, they’re kind of like type placeholders saying “this can be any concrete type that conforms to this protocol”.
Swift 5.1 lets you use these protocols as regular types with opaque result types [SE-0244].
In the Opaque Tutorials page, add some
to the return type of createBlogPost
, saying that it returns a concrete implementation of BlogPost
.
func createBlogPost(title: String, author: String) -> some BlogPost {
Similarly, in the Opaque Screencasts page, use some
to tell the compiler createBlogPost
returns some type of BlogPost
.
func createBlogPost(title: String, author: String) -> some BlogPost {
You may return any concrete type that implements BlogPost
from createBlogPost
: Tutorial
or Screencast
in this case.
Now, you can check if the previously created tutorials and screencasts are the same. At the bottom of Opaque Tutorials, paste the following to check if swift4Tutorial
and swift5Tutorial
are the same.
let sameTutorial = swift4Tutorial == swift5Tutorial
At the bottom of Opaque Screencasts, paste the following to check if swift4Screencast
and swift5Screencast
are the same.
let sameScreencast = swift4Screencast == swift5Screencast
Implicit Returns From Single-Expression Functions
You use return
in single-expression functions in Swift 5:
extension Sequence where Element == Int {
func addEvenNumbers() -> Int {
return reduce(0) { $1.isMultiple(of: 2) ? $0 + $1 : $0 }
}
func addOddNumbers() -> Int {
return reduce(0) { $1.isMultiple(of: 2) ? $0 : $0 + $1 }
}
}
let numbers = [10, 5, 2, 7, 4]
let evenSum = numbers.addEvenNumbers()
let oddSum = numbers.addOddNumbers()
You use reduce(_:_:)
in addEvenNumbers()
and addOddNumbers()
to determine the sum of even and odd numbers in Sequence
.
Swift 5.1 drops return
in single-expression functions so they behave like single-line closures in this case [SE-0255]:
extension Sequence where Element == Int {
func addEvenNumbers() -> Int {
reduce(0) { $1.isMultiple(of: 2) ? $0 + $1 : $0 }
}
func addOddNumbers() -> Int {
reduce(0) { $1.isMultiple(of: 2) ? $0 : $0 + $1 }
}
}
The code is cleaner and easier to follow this time.
reduce(_:_:)
works in Swift? Check out the functional programming tutorial: An Introduction to Functional Programming in Swift.