В Swift я пытаюсь реализовать метод «tap», похожий на метод, который существует в Ruby.
Я придумал следующий пример кода:
private protocol Tap {
mutating func tap(_ block: (inout Self) -> Void) -> Self
}
private extension Tap {
mutating func tap(_ block: (inout Self) -> Void) -> Self {
block(&self)
return self
}
}
extension Array: Tap {}
var a = Array(repeating: "Hello", count: 5)
a.tap {
$0.append("5")
}.tap {
$0.append("7")
}
print(a) // (Expected) => ["Hello", "Hello", "Hello", "Hello", "Hello", "5", "7"]
Я не очень знаком с изменяющими функциями, параметрами inout или Swift в целом, но приведенный выше код выглядит так, как будто он должен работать для меня. tap
работает должным образом, когда он не включен в цепочку методов. Когда я включаю его как часть цепочки методов, как в приведенном выше примере, компилятор Swift жалуется:
Невозможно использовать мутирующий член для неизменяемого значения: вызов функции возвращает неизменяемое значение
Может кто-нибудь объяснить мне, почему это не работает? Кто-нибудь может предоставить рабочее решение и объяснить, почему это решение работает?
Edit:
Другой пример использования будет:
let user = User(fromId: someId).tap {
$0.firstName = someFirstName
$0.lastName = someLastName
}
tap
- это удобство, которое приходит от Ruby. В основном меня интересует понимание того, почему типы в моей функции работают неправильно.