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 == Itemin the extension is the key part, which makes sureSelfis bound to a concrete typeItem.