프로토콜에 제네릭 및 제약조건 적용하기
제네릭 (범용 타입)은 런타임 시 타입을 결정하게하여 함수 또는 변수에 상황에 맞는 타입을
사용할 수 있게하는 기능이다.
제네릭 역시 프로토콜에 적용 할 수 있으며, 프로토콜 타입을 재네릭으로 사용할 수 있다.
1) 프로토콜에 제네릭 사용하기
기본 제네릭 패턴 또는 where과 조합해서 쓸 수 있다.
protocol SomeProtocol {
func f1<T: Equatable>(param: T) // 단순 제네릭 이용
func f2<T>(param: T) where T: Equatable // 제네릭 + where 이용
}
2) 제네릭에 프로토콜 타입으로 사용하기
프로토콜 역시 제네릭 타입으로 사용할 수 있다.
protocol SomeProtocol {
func someFunc() -> Void
}
class SomeClass: SomeProtocol {
func someFunc() {}
}
func genericFunc<T: SomeProtocol>(generic: T) -> Void {
generic.someFunc()
}
func genericFunc2<T>(generic: T) -> Void where T: SomeProtocol {
generic.someFunc()
}
프로토콜 합성
여러가지 프로토콜을 모두 만족해야할 때 & 연산자를 사용해서 표시한다.
가장 대표적인 프로토콜로는 Codable 프로토콜이 생각난다.
Codable = Decodable + Encodable 인 형태이다. 한번 진짜 그런지 확인해보자.
아래에서 보다시피 Codable은 새로운 프로토콜이 아닌 단순 Decodable 과 Encodable이 합성된 typealias이다.
프로토콜 선언 시 다음과 같이 사용할 수 도 있다.
protocol SomeProtocol {
func someFunc() -> Void
}
protocol SomeProtocol2 {
func someFunc2() -> Void
}
protocol SomeProtocol3: SomeProtocol & SomeProtocol2 {
func someFunc3() -> Void
}
class SomeClass: SomeProtocol3 {
func someFunc() {}
func someFunc2() {}
func someFunc3() {}
}
프로토콜 채택 체크
프로토콜은 체크 여부는 is, as , where을 통해 할 수 있다.
1) is
프로토콜을 준수하면 true 아니면 false
protocol SomeProtocol {
func someFunc() -> Void
}
class SomeClass: SomeProtocol {
func someFunc() {}
}
var someC = SomeClass()
if someC is SomeProtocol {
print("Some Class confirmed SomeProtocol") // ✅
} else {
print("Some Class doesn't confirmed SomeProtocol ") ❌
}
2) as
as는 구현체의 타입을 프로토콜 타입으로 변환한다.
as? 는 채택하지 않았을 경우 nil을 리턴 as!는 런타임 에러를 발생시킵니다.
guard let p = someC as? SomeProtocol else {
fatalError()
}
let pp = someC as! SomeProtocol
3) where
where은 크게 2가지 역할을 한다.
첫번 째는 특정 패턴과 조합하여 조건을 추가할 수 있고 두번 째는 재네릭 타입에 대한 제약을 추가할 수 있다.
우리는 프로토콜에 대한 사용을 배우고 있으므로 두번 째 역할을 이용한다.
func genericFunc2<T>(generic: T) -> Void where T: SomeProtocol {
generic.someFunc()
}
'프로그래밍언어 > swift' 카테고리의 다른 글
protocol 학습하기 (4) [ any, some ] (0) | 2024.08.25 |
---|---|
protocol 학습하기 (3) [ associatedtype ] (0) | 2024.08.25 |
protocol 학습하기 (1) [ property, method, extension ] (0) | 2024.08.24 |
생성자 (0) | 2024.08.24 |
class와 struct (0) | 2024.08.24 |