Void and the empty tuple in Swift
Void is a typealias for the empty tuple. Starting there, a short look at how the two behave.
- Published
This article is also published elsewhere. https://iganin.hatenablog.com/entry/2019/02/05/020129
Originally written in Japanese. This is a translation of the same piece.
Introduction
Today I went to a study group on Introduction to iOS App Design Patterns, hosted by UZUMAKI.
The subject was the MVVM architecture, but something interesting about the handling of Void and () came up
during the discussion, so I am writing it down.
Environment
- Xcode 10.0
- Swift 4.2
Void and the empty tuple
Void is a type, declared like this:
public typealias Void = ()
Because it is a type, you cannot pass it as an argument to a method — you have to pass an instance. In most
cases the argument you reach for is ().
let sampleRelay = PublishRelay<Void>()
// Put ( ) where the type is declared as Void.
sampleRelay.accept(())
And since Void is a typealias for (), () also works as a type:
let a: () = ()
Void being a type, it can also be instantiated:
let a = Void()
So anywhere you would assign (), assigning Void() works just as well. Void() is fine — but ()() is not.
It fails to compile with Cannot call value of non-function type '()'.
Summary
Rambling, but it comes down to this:
// Void is a type; () works as both a type and an instance
let a: () = () // OK
let b = () // OK
let c = Void() // OK
let d: Void = () // OK
let e = ()() // NG
let f: () = ()() // NG
This corner of the language is not something you normally think about, but poking at it is good fun. What
surprised me personally was that Void can be instantiated at all.