2. NHN NEXT Eunjoo Im
Generic
소개
▪ Generic code를 사용하면 타입을 제한하지 않으므로 중복
감소 및 의도의 명시적 표현 가능
▪ Swift의 중요 기능 중 하나로 많은 표준 라이브러리가 사용
▪ Int, String 등 컬렉션에 들어가는 타입을 명시하지 않고 어
느 타입이나 담을 수 있음
출처: Apple Inc. The Swift Programming Language (Swift 3.0.1)
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA = a
a = b
b = temporaryA
}
func swapTwoValues<T>(_ a: inout T, _ b: inout
T) {
let temporaryA = a
a = b
b = temporaryA
}
var someString = "hello"
var anotherString = "world"
swapTwoValues(&someString, &anotherString)
일반 function Generic function
type parameter
ex) Dictionary<Key, Value>
3. NHN NEXT Eunjoo Im
Generic
Type
▪ Array, Dictionary에 타입 제한 없이 넣을 수 있던 것처럼,
커스텀 class, structure, enumeration이 어떤 타입이라
도 사용할 수 있도록 할 수 있음
출처: Apple Inc. The Swift Programming Language (Swift 3.0.1)
struct IntStack {
var items = [Int]()
mutating func push(_ item: Int) {
items.append(item)
}
mutating func pop() -> Int {
return items.removeLast()
}
}
struct Stack<Element> {
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
}
일반 stack Generic function
4. NHN NEXT Eunjoo Im
Generic
Type
▪ Array, Dictionary에 타입 제한 없이 넣을 수 있던 것처럼,
커스텀 class, structure, enumeration이 어떤 타입이라
도 사용할 수 있도록 할 수 있음
출처: Apple Inc. The Swift Programming Language (Swift 3.0.1)
struct IntStack {
var items = [Int]()
mutating func push(_ item: Int) {
items.append(item)
}
mutating func pop() -> Int {
return items.removeLast()
}
}
struct Stack<Element> {
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
}
var stackOfStrings = Stack<String>()
stackOfStrings.push("one")
stackOfStrings.push("two")
일반 stack
Generic stack
5. NHN NEXT Eunjoo Im
Generic
Type
확장
▪ 확장 시 type parameter를 정의할 필요 없이 기존 타입
정의를 그대로 사용할 수 있음
출처: Apple Inc. The Swift Programming Language (Swift 3.0.1)
struct Stack<Element> {
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
}
// topItem이라는 읽기 전용 computed property 추가
extension Stack {
var topItem: Element? {
return items.isEmpty ? nil : items[items.count - 1]
}
}
기존 generic stack extension generic stack
기존 type parameter를 사용
6. NHN NEXT Eunjoo Im
Type
제약
▪ 모든 type을 받지 않고 특정 조건을 만족하는 타입만 사용
하도록 할 수 있음
▪ Swift Dictionary의 경우 Hashable 프로토콜을 따르는 타
입만 key로 사용 가능 (String, Int, Double, Bool)
출처: Apple Inc. The Swift Programming Language (Swift 3.0.1)
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) { // }type 제약 문법
func findIndex(ofString valueToFind:
String, in array: [String]) -> Int? {
for (index, value) in array.enumerated() {
if value == valueToFind {
return index
}
}
return nil
}
func findIndex<T: Equatable>(of valueToFind: T, in
array:[T]) -> Int? {
for (index, value) in array.enumerated() {
if value == valueToFind {
return index
}
}
return nil
}
T: Equatable
Equatable protocol을 따르는 T
안넣으면 == 조건문을 지원하지
않는 타입이 있으므로 에러
String array에서 특정 String 탐색 array에서 특정 T 탐색
7. NHN NEXT Eunjoo Im
연관
Type
▪ protocol의 일부로 사용될 type의 이름을 정의
▪ protocol 정의 시 함께 정의하면 편리함
▪ 실제 protocol이 적용될 때 사용됨
▪ associatedtype 키워드 사용
출처: Apple Inc. The Swift Programming Language (Swift 3.0.1)
// Container 프로토콜에서 ItemType이라는 연관 타입 정의
protocol Container {
associatedtype ItemType
mutating func append(_ item: ItemType)
var count: Int { get }
subscript(i: Int) -> ItemType { get }
}
append(_:) 메서드로
container에
새 아이템 추가 가능
Int 값을 반환하는 count 프로퍼티로
아이템 수 계산 가능
Int 인덱스 subsctipt를 통해 아이템에 접근 가능
8. NHN NEXT Eunjoo Im
출처: Apple Inc. The Swift Programming Language (Swift 3.0.1)
struct IntStack: Container {
// original IntStack implementation
var items = [Int]()
mutating func push(_ item: Int) {
items.append(item)
}
mutating func pop() -> Int {
return items.removeLast()
}
// conformance to the Container protocol
typealias ItemType = Int
mutating func append(_ item: Int) {
self.push(item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> Int {
return items[i]
}
}
struct Stack<Element>: Container {
// original Stack<Element> implementation
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
// conformance to the Container protocol
mutating func append(_ item: Element) {
self.push(item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> Element {
return items[i]
}
}
Container 프로토콜을 따르는 IntStack Container 프로토콜을 따르는 generic Stack
ItemType을 Int로 변환
append(_:) 메서드가
Element를 사용하므로
자동으로 타입 추론
9. NHN NEXT Eunjoo Im
Generic
Where문
▪ generic where문을 정의하여 연관 타입의 요구 사항을 정
의할 수 있음
▪ 연관 타입이 따라야할 프로토콜을 지정하거나, 특정 type
parameter와 일치하도록 지정할 수 있음
출처: Apple Inc. The Swift Programming Language (Swift 3.0.1)
// Check each pair of items to see
if they are equivalent.
for i in 0..<someContainer.count {
if someContainer[i] != anotherContainer[i] {
return false
}
}
// All items match, so return true.
return true
}
func allItemsMatch<C1: Container, C2: Container>
(_ someContainer: C1, _ anotherContainer: C2) -
> Bool
where C1.ItemType == C2.ItemType,
C1.ItemType: Equatable {
// Check that both containers
contain the same number of items.
if someContainer.count !=
anotherContainer.count {
return false
}
C1과 C2는 Container 프로토콜을 따름
C2의 ItemType은 Equatable을 따름
C1과 C2의 ItemType은 동일
10. NHN NEXT Eunjoo Im
Generic
Where문
출처: Apple Inc. The Swift Programming Language (Swift 3.0.1)
var stackOfStrings = Stack<String>()
stackOfStrings.push("one")
stackOfStrings.push("two")
stackOfStrings.push("three")
var arrayOfStrings = ["one", "two", "three"]
if allItemsMatch(stackOfStrings, arrayOfStrings) {
print("All items match.")
} else {
print("Not all items match.")
}
// Prints "All items match."