Then
В Kotlin
есть scope
-функции1 — функции, позволяющие запустить блок кода в контексте объекта.
В Swift
такого механизма нет, но его можно сделать самостоятельно или взять готовый.
Как это работает в Kotlin
? Давайте рассмотрим простой пример. Предположим, у нас есть дерево, которое выглядит так:
class TreeNode(var `val`: Int) {
var left: TreeNode? = null
var right: TreeNode? = null
}
И нам бы хотелось объявить всё необходимое нам дерево “за один раз”. Scope
-функция apply()
поможет нам это сделать:
TreeNode(1).apply {
left = TreeNode(2)
right = TreeNode(3)
}
Что нам потребуется, чтобы привнести похожее поведение в Switf
? В целом, сделать это не сложно. Можно
создать extension
со следующим методом:
public func then(_ block: (Self) throws -> Void) rethrows -> Self {
try block(self)
return self
}
Использоваться этот фрагмент будет следующим образом:
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
}
}
Теперь мы можем собрать дерево (или любой более сложный объект), один раз описав его инициализацию:
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)
}
Но на самом деле за нас уже подумали и всё сделали заранее. Весь сахар, описанный выше, хорошо умеет делать
библиотека Then
2. Устанавливается она так же просто, как и все зависимости:
...
dependencies: [
.package(url: "https://github.com/devxoul/Then", exact: "3.0.0"),
],
...
Не забудьте добавить саму зависимость в цель сборки:
...
.target(
name: "Solution",
dependencies: ["Then"]
),
...
Если работаете не со встроенными типами, добавьте к вашему собственному расширение Then
:
extension ListNode: Then {}