Z Swift 3, można wybrać jeden z trzech RandomNumbersSequence
wdrożeń w celu rozwiązania problemu.
1. Korzystanie z struct, który jest zgodny z protokołem Sequence
i struct zgodnego z IteratorProtocol
protokołu
Poniższy kod zabaw pokazuje jak zaimplementować RandomNumbersSequence
struct zgodnego z Sequence
i że używa RandomNumbersIterator
struct który jest zgodny z protokołem: IteratorProtocol
import Darwin // required for arc4random_uniform
struct RandomNumbersIterator: IteratorProtocol {
let maxNum: Int
var n = 0
init(maxNum: Int) {
self.maxNum = maxNum
}
mutating func next() -> Int? {
n += 1
return n <= self.maxNum ? Int(arc4random_uniform(10)) : nil
}
}
struct RandomNumbersSequence: Sequence {
let maxNum: Int
init(maxNum: Int) {
self.maxNum = maxNum
}
func makeIterator() -> RandomNumbersIterator {
return RandomNumbersIterator(maxNum: maxNum)
}
}
Wykorzystanie # 1:
for value in RandomNumbersSequence(maxNum: 3) {
print(value)
}
/*
may print:
5
7
3
*/
Zastosowanie 2:
let randomArray = Array(RandomNumbersSequence(maxNum: 3))
print(randomArray)
/*
may print: [7, 6, 1]
*/
Zastosowanie 3:
let randomSequence = RandomNumbersSequence(maxNum: 3)
var randomGenerator = randomSequence.makeIterator()
randomGenerator.next() // may return: 4
randomGenerator.next() // may return: 8
randomGenerator.next() // may return: 3
randomGenerator.next() // will return: nil
2. Za pomocą zgodnego z struct Sequence
i IteratorProtocol
protokołów
Następujący kod zabaw pokazuje, jak zaimplementować RandomNumbersSequence
struktura zgodnych Sequence
i IteratorProtocol
protokołów:
import Darwin // required for arc4random_uniform
struct RandomNumbersSequence: Sequence, IteratorProtocol {
let maxNum: Int
var n = 0
init(maxNum: Int) {
self.maxNum = maxNum
}
mutating func next() -> Int? {
n += 1
return n <= self.maxNum ? Int(arc4random_uniform(10)) : nil
}
}
Zastosowanie # 1:
for value in RandomNumbersSequence(maxNum: 3) {
print(value)
}
/*
may print:
5
7
3
*/
Zastosowanie 2:
let randomArray = Array(RandomNumbersSequence(maxNum: 3))
print(randomArray)
/*
may print: [7, 6, 1]
*/
Zastosowanie 3:
var randomSequence = RandomNumbersSequence(maxNum: 3)
randomSequence.next() // may return: 4
randomSequence.next() // may return: 8
randomSequence.next() // may return: 3
randomSequence.next() // will return: nil
3.Korzystanie AnyIterator
i struct zgodnego z Sequence
Jako alternatywę do poprzedniej realizacji, można użyć AnyIterator<T>
jako typ zwracanej metody makeIterator
wewnątrz swojej struktury protokołu Sequence
zgodnego. Poniższy kod zabaw pokazuje jak wdrożyć go z RandomNumbersSequence
struct:
import Darwin // required for arc4random_uniform
struct RandomNumbersSequence: Sequence {
let maxNum: Int
init(maxNum: Int) {
self.maxNum = maxNum
}
func makeIterator() -> AnyIterator<Int> {
var n = 0
let iterator: AnyIterator<Int> = AnyIterator {
n += 1
return n <= self.maxNum ? Int(arc4random_uniform(10)) : nil
}
return iterator
}
}
Wykorzystanie # 1:
for value in RandomNumbersSequence(maxNum: 3) {
print(value)
}
/*
may print:
5
7
3
*/
Wykorzystanie # 2:
let randomArray = Array(RandomNumbersSequence(maxNum: 3))
print(randomArray)
/*
may print: [7, 6, 1]
*/
Wykorzystanie # 3:
let randomSequence = RandomNumbersSequence(maxNum: 3)
let randomGenerator = randomSequence.makeIterator()
randomGenerator.next() // may return: 4
randomGenerator.next() // may return: 8
randomGenerator.next() // may return: 3
randomGenerator.next() // will return: nil
Tylko do sprawdzenia - próbujesz napisać e sekwencja, która podaje x liczbę liczb losowych? To znaczy. jeśli utworzysz 'let seq = RandomNumbersSequence (maxNum: 5)', to czy 'for i in seq {}' dostaniesz 5 liczb losowych? –