Как конвертировать Sequence в Array или в Swift есть конец Sequence? - PullRequest
0 голосов
/ 01 мая 2020

Согласно документации:

init (_ s: S) где Element == S.Element, S: Sequence
Создает массив, содержащий элементы последовательности.

struct Test: IteratorProtocol, Sequence {
    let id: Int

    init(_ id: Int) {
        self.id = id
    }

    mutating func next() -> Test? {
        id < 10 ? Test(id + 1) : nil
    }
}

let test = Test(5)
let arr = Array(test)

Компилируется. И даже не выдает никаких ошибок времени выполнения.
Но вместо того, чтобы в результате получить массив [5, 6, 7, 8, 9], я получаю бесконечное l oop! next() вызывается бесконечно много раз.
Я думал, что nil в next() является естественным индикатором конца последовательности. Но, видимо, это не так.

Ответы [ 3 ]

2 голосов
/ 01 мая 2020

self.id никогда не меняется, поэтому никогда не достигает 10.

1 голос
/ 01 мая 2020

Это должно быть примерно так

struct Test: IteratorProtocol, Sequence {
    var id: Int

    init(_ id: Int) {
        self.id = id
    }

    mutating func next() -> Test? {
       defer { id += 1 } 
       return id < 10 ? self : nil
    }
}

print(Array(Test(6)))

Другой пример

 struct Countdown: Sequence, IteratorProtocol {
     var count: Int

     mutating func next() -> Int? {
         if count == 0 {
             return nil
         } else {
             defer { count -= 1 }
             return count
         }
     }
 }

 let threeToGo = Countdown(count: 3)
 for i in threeToGo {
     print(i)
 }
 // Prints "3"
 // Prints "2"
 // Prints "1"
0 голосов
/ 02 мая 2020

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

последовательность (первая: следующая: )
Возвращает последовательность, сформированную из первого и повторного ленивых применений следующего.

struct Test {
    var id: Int

    init(_ id: Int) {
        self.id = id
    }
}

let seq = sequence(first: Test(5), next: { test in
    let id = test.id + 1
    return id < 10 ? Test(id) : nil
})

let arr = Array(seq)
...