Then
Kotlin has scope functions1 — functions that let you run a block of code in the context of an object. Swift has no such mechanism, but you can either build one yourself or use a ready-made one.
How does it work in Kotlin? Let’s look at a simple example. Suppose we have a tree that looks like this:
class TreeNode(var `val`: Int) {
var left: TreeNode? = null
var right: TreeNode? = null
}
And we’d like to declare the entire tree we need “in one go”. The apply() scope function will help us do that:
TreeNode(1).apply {
left = TreeNode(2)
right = TreeNode(3)
}
What do we need to bring similar behavior to Swift? It’s not hard, really. We can create an extension with the following method:
public func then(_ block: (Self) throws -> Void) rethrows -> Self {
try block(self)
return self
}
This snippet will be used as follows:
public class TreeNode {
public var val: Int
public var left: TreeNode?
public var right: TreeNode?
init(val: Int) {
self.val = val
}
}
extension TreeNode {
public func then(_ block: (Self) throws -> Void) rethrows -> Self {
try block(self)
return self
}
}
Now we can assemble the tree (or any more complex object) by describing its initialization just once:
let tree = TreeNode(val: 1).then { it in
it.left = TreeNode(val: 2).then { it in
it.left = TreeNode(val: 5)
it.right = TreeNode(val: 7)
}
it.right = TreeNode(val: 3)
}
But in fact, someone has already thought of this and done all the work for us. All the sugar described above is handled
nicely by the Then2 library. It’s installed as easily as any other dependency:
...
dependencies: [
.package(url: "https://github.com/devxoul/Then", exact: "3.0.0"),
],
...
Don’t forget to add the dependency itself to your build target:
...
.target(
name: "Solution",
dependencies: ["Then"]
),
...
If you’re working with something other than the built-in types, add a Then extension to your own type:
extension ListNode: Then {}