제네릭이란?
•
타입에 의존하지 않는 범용 코드를 작성할 떄 사용하며, 중복을 피하고 코드를 유연하게 작성할 수 있다.
◦
swift의 표준 라이브러리의 대다수는 제네릭으로 선언
•
배열, 딕셔너리, 세트는 제네릭 컬렉션이다.
//제네릭을 사용하고자 하는 타입 이름 <타입 매개변수>
//제네릭을 사용하고자 하는 함수 이름 <타입 매개변수> (함수의 매개변수)
Swift
복사
제네릭 함수
예)
func swapTwoValues<T>(_ a: inout T, _ b: inout T) {
let tempA = a
a = b
b = tempA
}
Swift
복사
•
<>를 이용하여 안에 타입처럼 사용할 이름(T)를 선언하면 해당 이름을 타입처럼 사용가능
•
T = Type Parameter
◦
새로운 형식이 생성되는 것이 아닌 실제 함수가 호출될 때 매개변수의 타입으로 대체되는 Placeholder
제네릭 타입
•
구조체, 클래스, 열거형 타입에도 선언 가능
타입 제약
•
제네릭 함수와 타입을 사용할 때 특정 클래스의 하위 클래스나, 특정 프로토콜을 준수하는 타입만 받을 수 있게 제약을 둘 수 있다.
예) 두 값을 받아 같은지 다른지 판별 하는 함수
func sameValue<T>(a: T, b: T) -> Bool {
return a == b
}
//Binary operator '==' cannot be applied to two 'T' operands
Swift
복사
•
== 이라는 연산자는 a와 b의 타입이 Equatable이란 프로토콜을 준수할 때만 사용가능
•
a, b가 Equatable 프로토콜을 준수하는 타입인지 아닌지 불분명하기 때문에 오류가 발생
func sameValue<T: Equatable>(a: T, b: T) -> Bool{
return a == b
}
Swift
복사
•
T : Equatable 라고 제약을 주면 Equatable이란 프로토콜을 준수하는 매개변수만 받는다.
프로토콜이란?
•
특정 역할을 하기 위한 메소드, 프로퍼티, 기타 요구사항 등의 청사진
•
구조체, 클래스, 열거형은 프로토콜을 채택해 특정 기능을 실행하기 위한 프로토콜의 요구사항을 실제로 구현할 수 있다.
•
프로토콜은 정의를 하고 제시를 할 뿐 스스로 기능을 구현하지는 않는다.(조건만 정의)
•
하나의 타입으로 사용되기 때문에 타입 사용이 허용되는 모든 곳에 프로토콜을 사용할 수 있다.
◦
예) 함수, 메서드, 이니셜라이저의 파라미터 타입, 리턴 타입
◦
상수, 변수, 프로퍼티의 타입
◦
배열, 딕셔너리의 원소 타입
기본형태
protocol 프로토콜이름 {
//프로토콜 정의
}
Swift
복사
구조체, 클래스 등에서 프로토콜을 채택하려면 타입 이름 뒤에 ‘:’ 을 붙여 채택할 프로토콜 이름을 ‘,’로 구분하여 명시
struct SomeStruct : Aprotocol, AnotherProtocol {
//구조체 정의
}
//상속받는 클래스의 프로토콜 채택
class SomeClass : SuperClass, Aprotocol, AnotherProtocol {
//클래스 정의
}
Swift
복사
•
프로토콜에서는 프로퍼티가 저장프로퍼티인지 연산프로퍼티인지 명시하지 않고, 이름과 타입 그리고 gettable, settable한지 명시한다.
•
프로퍼티는 항상 var로 선언해야 한다.
프로토콜에서는 인스턴스 메서드와 타입 메서드를 정의할 수 있다.
•
메소드 파라미터의 기본 값은 프로토콜 안에서 사용할 수 없다.
•
메소드를 정의할 때 함수명과 반환값을 지정할 수 있고, {}는 적지 않는다.
protocol Person {
static func breathing()
func sleeping(time: Int) -> Bool
mutating func running()
}
Swift
복사
프로토콜에서 제네릭을 사용하려면 associatedtype 을 사용해야 한다.
정리
제네릭
제네릭은 중복을 피하고 코드를 유연하게 작성하기 위한
타입에 의존하지 않는 범용 코드이다.
프로토콜
프로토콜은 실제로 구현하는 것이 아니라
“이런 이런 프로퍼티는 필요해요 !”
“이런 이런 메서드도 필요해요 !”
라고 해당 기능에 필요한 요구 사항을 선언해 두는 것