Sequence Type (프로토콜)

위의 계층 구조를 보면 모든 것들이 Sequence프로토콜을 기반으로 작성되었다는 사실을 알 수 있습니다.
Array타입을 사용할때 Sequence가 대부분의 기능을 제공합니다. map, filter뿐만아니라 Sequence안에 특정 조건을 만족하는 첫번째요소찾는 기능까지, 모두 다 Sequence프로토콜 안에 정의되어있습니다.
Sequence가 가장 단순한 것이고, 나머지는 Sequence를 기반으로 작성된것들입니다.
[정의]
- 해당 요소에 대한 순차반복 엑세스를 제공하는 유형입니다.
예시) 문자열 값, 배열, 컬렉션타입의 값들?
[특징]
- 시퀀스는 한 번에 하나씩 단계별로 수행할 수 있는 값의 목록이다. 시퀀스의 요소를 반복하는 가장일반적인 방법은
for in 루프를 사용하는것이다. - 즉, 반복문을 돌릴 수 있으면 Sequence Type의 프로토콜을 채택하고 있다고 볼 수 있다.
let oneTwoThree = 1...3
for number in oneTwoThree {
print(number)
}
단순해 보이지만 이 기능을 사용하면 모든 시퀀스에서 수행할 수 있는 많은 작업에 접근할 수 있다.
예로 시퀀스에 특정 값이 포함되어 있는지 확인하기 위해 일치하는 항목을 찾거나 시퀀스의 끝에 도달할 때 까지
각 값을 순차적으로 테스트할 수 있다.
특정 camper가 있는지 확인해봅시다.
let campers = ["Donnie", "Minseong", "safari", "oneTool", "quokka"]
var hasQuokka = false
for camper in campers {
if camper == "quokka" {
hasQuokka = true
break
}
}
print("bugs has a mosquito: \(hasQuokka)")
시퀀스 프로토콜은 시퀀스 값에 대한 순차적인 접근에 의존하는 많은 공통작업에 대한 기본구현을 제공합니다.
또는 더 명확하고 간결한 코드에서 위의 예는 수동으로 반복하는 대신 모든 시퀀스가 Sequence에서 상속하는 배열의 contains메서드를 사용할 수 있습니다.
if campers.contains("quokka") {
print("Hi! quokka Im here!")
} else {
print("where is the quokka!")
}
반복 접근
:###중요###
:`Sequence 프로토콜은 반복에 의해 파괴적으로 소비되는지 여부와 관련하여 형식 준수에 대한 요구사항이 없습니다.
결과적으로 시퀀스의 여러 for-in루프가 반복을 재개하거나 처음부터 다시 시작할 것이라고 가정하지 않아야한다.
즉, 한번만 반복할 수 있음
컬렉션이 아닌 일치하는 시퀀스는 두 번째 for-in루프에서 임의의 요소 시퀀스를 생성할 수 있습니다.
`
- 생성한 유형이 비파괴 반복을 지원하는지 확인하려면 Collection프로토콜에 대한 준수를 추가하십시오.
시퀀스 프로토콜 채택
사용자 정의 타입을 시퀀스에 따르도록하면 많은 노력없이 for-in 루핑 및 포함메소드와 같은 많은 유용한 작업이 가능힙니다.
고유한 사용자 정의 유형에 시퀀스 준수를 추가하려면 반복자를 리턴하는 makeIterator()메서드를 추가하세요
또는 유형이 자체적으로 반복할 수 있는경우 IteratorProtocol요구사항을 구현하고 sequence 및 IteratorProtocol모두에 대한 적합성을 선언하는것으로 충분합니다.
//struct Countdown: 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 index in threeToGo { // error: For-in loop requires 'Countdown' to conform to 'Sequence'
// print(index)
//}
시퀀스 프로토콜을 채택하지않고는 에러가발생합니다. 반복문의 range조건에는 시퀀스 요소만 들어갈 수 있기때문입니다.
그래서 아래 예시에서는 에러가 나지않는걸 볼 수 있습니다.
struct Countdown: Sequence, IteratorProtocol {
var count: Int
mutating func next() -> Int? {
if count == 0 {
return nil
} else {
defer { count -= 1 }
return count
}
}
}
struct Countdown2 {
var count: Int
}
let threeToGo = Countdown(count: 3)
print(threeToGo)
for index in threeToGo {
print(index)
}
for index in Countdown2(count: 3) {
print(index)
}
성능에대한 예상은 ?
시퀀스는 O(1)에서 반복자를 제공해야합니다.
시퀀스 프로토콜은 요소 액세스에 대한 다른 요구사항을 만들지 않으므로 달리 문서화되지않는 한 시퀀스를 통과하는 루틴은 O(n)으로 간주되어야 합니다.
Reference
- [Sequence공식문서](https://developer.apple.com/documentation/swift/sequence)
- [시퀀스와 컬렉션의 차이에 대한 자세한 내용](https://academy.realm.io/kr/posts/try-swift-soroush-khanlou-sequence-collection/)
'문법' 카테고리의 다른 글
[Swift] CoreData 속성 중 있는 Transformable 타입은 어디에쓰이나? (0) | 2022.06.29 |
---|---|
[Swift] ARC에 대해 간단히 알아보잡(feat. 클로저캡쳐) (0) | 2022.03.28 |
[Swift] Class와 struct 중 어느것을 선택해야할까 ? (0) | 2022.02.22 |
[Swift] 타입(Type Casting)캐스팅이란? (0) | 2022.02.22 |
[Swift] Error Handling[1편] 알아보자! (0) | 2022.02.19 |