Глубокое копирование замыканий в Swift - PullRequest
0 голосов
/ 07 сентября 2018

У меня есть функция, которая циклически перебирает массив функций, вызывая их по порядку с бесконечно переданными аргументами.

public extension Array {
    /// Cycles the elements in `self` infinitely.
    /// - warning: Do not call on an empty array.
    public func cycle() -> UnfoldSequence<Element, Int> {
        let count = self.count
        return sequence(state: 0, next: { (index: inout Int) in
            let x = self[index]
            index = (index + 1) % count
            return x
        })
    }
}

func cycle(funcs: [(((Int, Int)) -> (Int, Int))]) -> (((Int, Int)) -> (Int, Int)) {
    var cycled = funcs.cycle()
    return  { (coords) in
        let current = cycled.next()!
        return current(coords)
    }
}

Так, если у меня есть эти две функции, например:

func leftPattern(tuple:(x: Int, y: Int)) -> (Int, Int) {
    return (tuple.x, tuple.y - 1)
}

func upPattern(tuple:(x: Int, y: Int)) -> (Int, Int) {
    return (tuple.x - 1, tuple.y)
}

Я могу бесконечно переключаться между ними:

let leftUp = cycle(funcs: [leftPattern, upPattern])

leftUp будет равно ...

[leftPattern, upPattern, leftPattern, upPattern, ...]

Проблема в том, что мне нужен способ перезапустить эту последовательность, потому что, когда я передаю эту функцию, она начинается с неправильной части последовательности.

Поскольку функции передаются по ссылке, я подумал о том, чтобы как-то глубоко скопировать мою сгенерированную функцию, например:

let leftUp2 = copy(leftUp)
leftUp(...) // would use leftPattern for example
leftUp2(...) // would ALSO use leftPattern, not affected by calling leftUp before

Возможно ли это?

...