GQ1. Protocol Extension이 뭘까?
GQ2. 사용하면 뭐가 좋을까?
Description
개념
| 정의 가능 항목 | 설명 | 예시 코드 |
|---|
| 메서드 (Method) | 프로토콜에서 선언된 함수의 기본 동작 제공 | func prepareForStudy() { ... } |
| 계산 프로퍼티 (Computed Property) | 저장은 못하지만 계산 결과를 반환하는 프로퍼티 제공 | var motto: String { "Hello World" } |
| 서브스크립트 (Subscript) | 특정 타입에 인덱싱 기능 제공 | subscript(index: Int) -> String { ... } |
| 중첩 타입 (Nested Type) | enum, struct, class 등 타입 내부 정의 | enum StudyStyle { case silent, handsOn } |
| 제약 조건이 걸린 확장 (Conditional Extension) | 특정 타입일 때만 적용 | extension Collection where Element: Equatable |
장점
- 공통 코드를 한 번에 정의하여 코드 중복을 방지하고 일관성을 유지하게 한다.
기본 예시
protocol Describable {
var name: String { get }
func describe()
}
extension Describable {
func describe() {
print("This is \(name)")
}
var uppercasedName: String {
name.uppercased()
}
enum Style {
case short, detailed
}
}
현실 예시
1. 공통 기능을 묶은 Ssg 프로토콜
protocol Ssg {
func study()
}
2. Ssg 프로토콜을 확장해서 공통되는 동작은 기본 구현으로 제공
extension Ssg {
func prepareForStudy() {
print("주제를 정하고 이슈를 판다🔥")
}
}
전체 코드 (실행 가능 🙆♀️)
import Foundation
protocol Ssg {
func study()
}
extension Ssg {
func prepareForStudy() {
print("주제를 정하고 이슈를 판다🔥")
}
}
struct Jam: Ssg {
func study() {
print("브랜치 파자마자 성실하게 공부 시작🧐")
}
}
struct Gus: Ssg {
func study() {
print("팀장에게 점수를 따기 위해 노력함🕺")
}
}
let jam = Jam()
jam.prepareForStudy()
jam.study()
let gus = Gus()
gus.prepareForStudy()
gus.study()
+ Protocol Extension을 사용하지 않았더라면?
- 아래와 같이 공통되는 코드를 반복해서 구현해야 했겠죠!
struct Jam: Ssg {
func prepareForStudy() {
print("주제를 정하고 이슈를 판다🔥")
}
func study() {
print("브랜치 파자마자 성실하게 공부 시작🧐")
}
}
struct Gus: Ssg {
func prepareForStudy() {
print("주제를 정하고 이슈를 판다🔥")
}
func study() {
print("팀장에게 점수를 따기 위해 노력함🕺")
}
}
조건부 확장
현실 세계 예시
1. 팀장만 채택할 프로토콜 생성
protocol TeamLeader {
func giveScore(to member: Ssg)
}
2. TeamLeader만 giveScore()를 쓸 수 있도록 조건부 제한걸기
extension Ssg where Self: TeamLeader {
func giveScore() {
print("\(self.name) 팀장이 \(member.name)에게 점수를 준다")
}
}
전체 코드 (실행 가능 🙆♀️)
import Foundation
protocol Ssg {
func study()
}
protocol TeamLeader {
func giveScore()
}
extension Ssg where Self: TeamLeader {
func giveScore() {
print("팀원들에게 점수를 줌🎉")
}
}
struct Jam: Ssg {
func study() {
print("브랜치 파자마자 성실하게 공부 시작🧐")
}
}
struct Gus: Ssg {
func study() {
print("팀장에게 점수를 따기 위해 노력함🕺")
}
}
struct Jay: Ssg, TeamLeader {
func study() {
print("솔선수범하여 미리미리 공부함📑")
}
}
let jam = Jam()
jam.study()
let gus = Gus()
gus.study()
let jay = Jay()
jay.study()
jay.giveScore()
실제 예시
Collection 안의 요소가 Equatable일 때만 비교(==)가 가능
- 따라서
Element: Equatable일 때만 allEqual() 메서드를 사용할 수 있게함
extension Collection where Element: Equatable {
func allEqual() -> Bool {
guard let first = self.first else { return true }
return !self.contains { $0 != first }
}
}
| 타입 | 설명 |
|---|
Int, Double, Float | 숫자 비교 가능 |
String, Character | 문자열 비교 가능 |
Bool | true/false 비교 가능 |
References