Using leading dot syntax in generic functions
Leading dot syntax in Swift
The “leading dot syntax” is an important feature in Swift to provide clean and concise APIs for callers. It supports enums and static members.
Let’s say we have an ItemStorage
class that can store Item
. We can define Item
as enum
:
class ItemStorage { |
At the call site, we can just use .one
in the store(_:)
function:
let storage = ItemStorage() |
Alternatively, we can change Item
to struct
and declare commonly used values as the static variables to make them available in leading dot syntax:
struct Item { |
The problem: Generic functions ft. static members
Let’s say we want to expand ItemStorage
to support any types that conform to a protocol StorableItem
:
protocol StorableItem { |
We can make the existing Item
struct conform to the new protocol because it already has the identifier
property:
struct Item: StorableItem { |
But .someItem
no longer works:
let storage = ItemStorage() |
The solution
In Swift 5.5, leading dot syntax is extended to support static member lookup declared in the extension of protocols if the declaring extension or member itself constrains Self
to be a concrete type[1].
Here’s how to fix our example:
extension StorableItem where Self == Item { |
ℹ️ Note
where Self == Item
in the extension is the key part, which makes sureSelf
is bound to a concrete typeItem
.