Letan
(Letanyan Arumugam)
May 2, 2018, 3:34pm
19
I'll quote the comment I referred to up-thread inline here:
There have been a couple times where I've written code that needed to generically serve instances of a type T, and in each of those cases—thanks to Swift's support for first-class functions and initializers-as-functions—I found it to be cleaner to have my factory take a () -> T as a parameter and I pass T.init into that, rather than place constraints on T itself.
This approach doesn't require imposing any additional constraints on T. Even though it's trivial to use an extension to add conformance like DefaultConstructible to many existing types, the latter approach excludes any type that does not make sense to have a default initializer, or where the default initializer isn't what you want to use. Maybe you want to have your factory use a static method to create the objects of a certain type instead: passing the function reference lets you do that. The function can even be a closure that captures outer context, letting your factory work for types that need additional parameters passed to the creation method.
In general, I think talking about factories as "a thing that needs to call a specific initializer on a type" is a discussion motivated by patterns in other languages that are more restrictive than Swift. If you think of a factory instead as "something you can call that returns a T", the functional approach is much more powerful and general.
Not true. I've needed it and done it before (twice). In fact, I even called it DefaultInit
in my code. I can't remember what it was for now though. But as the comment above mentions, there are better ways of solving these problems in Swift.