티스토리 뷰
출처
제네릭
제네릭이 해결하는 문제
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temp = a
a = b
b = temp
}
var someInt = 3
var anotherInt = 10
swapTwoInts(&someInt, &anotherInt)
위와 같은 코드를 자료형 별로 모두 만들 필요가 없게해준다.
제네릭 함수
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
let temp = a
a = b
b = temp
}
위 함수는 Int, Double, String 등 모든 자료형에서 사용할 수 있다.
타입 매개변수, 이름짓기
제네릭 타입
아래와 같이 Int 로 정의되어 있는 것을 Element 라는 타입으로 변경할 수 있다.
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()
}
}
타입 제약
func someFunction<T: SomeClass, U: SomeProtocol>(someT: T, someU: U) {
}
타입 제약 동작
func findIndex(ofString valueToFind: String, in array: [String]) -> Int? {
for (index, value) in array.enumerated() {
if value == valueToFind {
return index
}
}
return nil
}
위 코드를 제네릭으로 변경하기위해 아래처럼 작성하면 complie error 가 난다.
func findIndex<T>(ofString valueToFind: T, in array: [T]) -> Int? {
for (index, value) in array.enumerated() {
if value == valueToFind {
return index
}
}
return nil
}
그 이유는 Swift 의 모든 타입이 동등연산자 ( == ) 로 비교되는 것이 아니기 때문에
value == valueToFInd 를 추측할 수 없다.
동등연산자로 비교하기 위해 타입을 제약한다.
func findIndex<T: Equatable>(ofString valueToFind: T, in array: [T]) -> Int? {
for (index, value) in array.enumerated() {
if value == valueToFind {
return index
}
}
return nil
}
연관된 타입
연관 타입 동작
protocol Container {
associatedtype Item
mutating func append(_ item: Item)
var count: Int { get }
subscript(i: Int) -> Item { get }
}
struct Stack<Element>: Container {
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
//MARK: Container
mutating func append(_ item: Element) {
push(item)
}
var count: Int {
return items.count
}
subscript(i: Int) -> Element {
return items[i]
}
}
제네릭 Where 절
func allItemsMatch<C1: Container, C2: Container>(_ item1: C1, _ item2: C2) -> Bool
where C1.Item == C2.Item, C1.Item: Equatable {
if item1.count != item2.count {
return false
}
for i in 0..<item1.count {
if item1[i] != item2[i] {
return false
}
}
return true
}
제네릭 where 절이 있는 확장
extension Stack where Element: Equatable {
func isTop(_ item: Element) -> Bool {
guard let topItem = items.last else {
return false
}
return topItem == item
}
}
만약 요소들이 equatable 하지 않은 Stack 에서 isTop method 를 호출하면
compile 에러가 발생한다.
extension Container where Item: Equatable {
func startsWith(_ item: Item) -> Bool {
return count >= 1 && self[0] == item
}
}
'iOS 개발 > Swift' 카테고리의 다른 글
[Swift 3] 옵셔널 체이닝 (Optional Chaining) (0) | 2017.04.18 |
---|---|
[Swift 3] ARC (Automatic Reference Counting) (0) | 2017.04.18 |
[Swift 3] 프로토콜 (Protocols) (0) | 2017.04.16 |
[Swift 3] 해제 (Deinitialization) (0) | 2017.04.15 |
[Swift 3] 초기화 (Initialzer) (0) | 2017.04.15 |
- Total
- Today
- Yesterday
- Swift 3
- CIImage
- Block
- optional
- docker
- EffectiveObjectiveC
- set
- coredata
- string
- AWS
- delegate
- NSManagedObjectModel
- RunLoop
- CGImage
- Swift
- Arc
- UIView
- NSManagedObject
- 꺼내먹어요
- Swift 3.0
- Swift3
- applicationWillResignActive
- HTTP
- thread
- NSManagedObjectContext
- dictionary
- Swfit
- 읽기 좋은 코드가 좋은 코드다
- workerThread
- ios
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |