티스토리 뷰
제네릭
- 여러 타입에 유연하게 대응할 수 있음
- 재사용하기 쉽고 코드의 중복을 줄일 수 있음
- 깔끔하소 추상적인 표현 가능해짐
- 많은 표준 라이브러리가 수많은 제네릭 코드로 구성되어 있음
- 제네릭을 사용할 때는 제네릭이 필요한 타입 또는 메서드의 이름뒤의 <>사이에 타입 매개변수를 써주어 제네릭을 사용할 것임을 표시함
- (제네릭을 사용하고자 하는 타입 이름) <타입 매개변수>
- (제네릭을 사용하고자 하는 함수 이름) <타입 매개변수> (함수의 매개변수 … )
- Array 타입
- Array는 타입 매개변수 Elemnet가 있고, map 메서드는 매개변수 T가 있음
- Array는 제네릭을 사용하는 제네릭 타입, map 메서드는 제네릭을 사용하는 제네릭 함수
public stuct Array<Element> : // 생략
// 중략
public func map<T>
// 중략
- 전위연산자 **를 Int가 아닌 정수타입 프로토콜일 경우 연산자를 사용할 수 있도록 구현
import UIKit
prefix operator **
prefix func ** <T: BinaryInteger> (value: T) -> T {
return value * value
}
let minusFive = -5
let five: UInt = 5
let sqrtMinusFive = **minusFive
let sqrtFive: UInt = **five
print(sqrtMinusFive) // 25
print(sqrtFive) // 25
- 제네릭을 사용ㅇ하지 않은 swapToInts 함수
- Int가 아닌 Double이나 String은 바꿀 수 없고 함수 다시 만들어야함
func swapTwoInts(_ a: inout Int, _ b: inout Int) {
let temporaryA: Int = a
a = b
b = temporaryA
}
var numberOne = 5
var numberTwo = 10
swapTwoInts(&numberOne, &numberTwo)
print(numberOne) // 10
print(numberTwo) // 5
- 함수에서 Int 대신 Any를 사용할 수 있지만, 해당 경우에는 Int는 Int끼리만 교환, String은 String끼리 교환하려고 할 때, 제한을 할 수 없음
- 추가로, Any타입만 전달할 수 있고, String값을 그대로 전달할 수 없음
제네릭 함수
// 제네릭을 사용한 swapTwoValues 함수
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
let temporaryA = a
a = b
b = temporaryA
}
- 제네릭 함수는 실제 타입 이름(Double, Any 등)을 써주는 대신 Placeholder(위 함수에서는 T)를 사용함
- 플레이스홀더는 타입의 종류를 알려주지 않고, 어떤 타입이라는 것을 알려줌
- 두 매개변수는 둘다 T이기 때문에, 같은 타입
- T의 실제 타입은, 함수가 호출되는 순간에 결정됨. Int 타입의 변수가 전달되면 T는 Int가 되고, Double 타입의 변수가 전달되면 Double이 됨
- 제네릭 함수의 플레이스 홀더를 지정하는 방법은 함수 이름 오른쪽에 <>기호를 사용하고 기호 안쪽에 플레이스 홀더 이름들을 나열하는 것
- 하나의 타입 매개변수가 아니라 여러개의 타입 매개변수를 갖고 싶다면 <T, U, V>처럼 사용할 수 있음
제네릭 타입
// 제네릭을 사용하지 않은 InStack 구조체
struct IntStack {
var items = [Int]()
mutating func push(_ item: Int) {
items.append(item)
}
mutating func pop() -> Int {
return items.removeLast()
}
}
var intStack: IntStack = IntStack()
// 제네릭을 사용한 InStack 구조체
struct Stack<Element> {
var items = [Element]()
mutating func push(_ item: Element) {
items.append(item)
}
mutating func pop() -> Element {
return items.removeLast()
}
}
var stack: Stack<Int> = Stack<Int>()
stack.push(1)
var stringStack: Stack<String> = Stack<String>()
stringStack.push("1")
- Stack 구조체는 IntStack와 달리 Element 타입 매개변수를 사용했음
- 구조체를 선언할 때, 어떤 타입을 사용할 지 명시해주는 방법은 Stack처럼 선언해주면 됨
제네릭 타입 확장
- 제네릭을 사용하는 타입에 익스텐션으로 기능을 추가한다면, 타입 매개변수를 명시하지 않아야함
- 대신 원래의 재네릭 정의에 명시한 타입 매개변수를 사용
// Stack 구조체의 익스텐션
extension Stack {
var topElement: Element? {
return self.items.last
}
}
타입 제약
- 제네릭 함수가 처리해야할 기능이 특정 타입에 한정되어야 처리할 수 있는 경우, 특정 프로토콜을 따르는 타입에 한정되어야 하는 경우가 있음
- 타입 제약을 통해서 제약사항을 지정할 수 있음
- 타입 매개변수가 특정 클래스를 상속받은 타입이나 특정 프로토콜을 준수하는 타입이어야 한다는 조건 등의 제약을 지정할 수 있음
- 클래스와 프로토콜만 제약으로 지정할 수 있고, 열거형이나 구조체는 불가능함
// 제네릭 타입 제약의 예시
func swapTwoValues<T: BinaryInteger>(_ a: inout T, _ b: inout T) {
// 함수 구현
}
struct Stack<Element: Hashable> {
// 구조체 구현
}
- 하나의 제약이 아니라 여러 제약을 추가하고 싶다면 where 절을 사용해서 제약을 추가 할 수 있음
// 여러 제약을 지정한 메서드
func swapTwoValues<T: BinaryInteger>(_ a: inout T, _ b: inout T) where T: FloatingPoint {
// 함수 구현
}
- 위 메서드는 두 프로토콜을 준수하는 타입이 존재하지 않음, 함수를 중복으로 정의하거나 새로운 타입을 정의해서 사용해야함
- 타입 매개변수가 여러개라면, 타입 매개변수마다 제약 조건을 다르게 지정할 수 있음
'programming > Swift' 카테고리의 다른 글
[Swift/iOS] 인스턴스 메소드와 타입메소드, static 메소드와 class 메소드 (0) | 2022.10.25 |
---|---|
[Swift/iOS] 제네릭(2) (0) | 2022.10.21 |
[Swift/iOS] 컴파일러 제어 구문 (0) | 2022.10.08 |
[Swift/iOS] 열거형(1) (1) | 2022.10.08 |
앱 출시 후기 - Repret 과거 주가 확인, 만약 그때 샀으면... (1) | 2022.10.05 |
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- SWIFT
- Persistent Container
- identity Token
- ios
- weak
- 회원가입
- inout 파라미터 메모리 충돌
- core data
- ASAuthorizationAppleIDCredential
- Delegate 패턴
- object
- autoclosure
- 클로저 강한 참조
- 토큰저장
- unowned
- 클로저
- CoreData
- 메모리 안정성
- 디자인패턴
- authorizationCode
- 클로저표현
- 자동클로저
- escaping closrue
- Entity
- 클로저 축약
- 캡쳐리스트
- context
- Core Data Stack
- 강한참조순환
- 강한 참조 순환
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함