Swift has first class functions that can be passed as arguments.
func a() {
}
func b(x: ()) {
}
// Pass a to b…
b(a)
Swift has generic functions.
func generic<T>(x: T) {
}
But, does Swift let me pass a generic function as an argument to another function?
let anIntService = Service<Int>()
let astringService = Service<String>()
func attach<T>(service: Service<T>, to value: T) {
// Perform type safe attaching of `value` to `service`.
}
func doAttaching(attach: (Service<T>, to T)->Void) {
attach(anIntService, to: 42)
attach(aStringService, to: "Hello World!")
}
doAttaching(attach)
…Or does it only let me pass a specific instantiation of a generic function?
If this is possible, please illustrate the syntax for defining a function that accepts a generic function as an argument.
If this isn't supported, a workaround is to define the generic function as a method of a struct, or something, and pass an instead of that. This is not ideal though, as the consuming function doesn't get such a nice calling syntax, they need to do:
func doAttaching(attach: Attacher) {
attacher.attach(anIntService, to: 42)
attacher.attach(aStringService, to: "Hello World")
}
I realised, five years after asking this question, Swift supports something a little like this which can be useful via callAsFunction
.
Here's an example:
final class Service<T> {
// Implementation here
}
final class Attacher {
// Important state here.
var state = Void()
func callAsFunction<T>(service: Service<T>, to: T) {
// Implementation here.
}
}
func doAttaching(attach: Attacher) {
attach(service: Service<Int>(), to: 42)
attach(service: Service<String>(), to: "Hello World!")
}
A Repeater
can be passed in to generic code and provide useful behaviour.