본문 바로가기

iOS/Swift

Swift) Protocol 이해하기 (5/6) - associatedtype :: Protocol의 Generic

 

 

안녕하세요! 블로그를 새단장한 소들입니다!!!

앞으론 제 글 마다 위 로고가 보일테니 참아주세요 하하하!!

이번 포스팅은 Protocol의 associatedtype에 대해 알아볼 거예요!!

 

혹시 범용 타입인 Generic을 잘 모르신다면 이 포스팅을 먼저 보고 와주세용!!

Generic을 안다는 가정 하에 포스팅을 진행할 거예용

이번 포스팅에선 Protocol에서 Generic을 사용하는 방법에 대해 알아볼 거예요!

내용이 간단하나 처음에는 좀 헷갈리고 어려울 수도 있습니당!

모든 포스팅은 편의 말투로 합니다~!!

 

 

 

 

1. 기존 Generic을 사용할 떈 말이죠

 

먼저 여러분 제네릭에 대해 간단하게 다시 짚고 가자몀

제네릭은 머다??

 

제네릭이란 타입에 의존하지 않는 범용 코드를 작성할 때 사용한다

제네릭을 사용하면 중복을 피하고, 코드를 유연하게 작성할 수 있다

 

코드의 중복을 줄이기 위해 사용하는 게 범용 ㅌ ㅏ입이다!!!

따라서 다음과 같이 구조체(or 클래스 or 메서드 등)에서 제네릭을 사용하고 싶으면

 

 

struct Stack<T: Equatable> {
    func push(value: T) { }
    func pop() -> T { ... }
}

 

 

이런 식으로 타입 네임 옆에 <>와 타입 파라미터(Type Parameter)인 T를 이용해서 작성 했잖음??

물론 위처럼 어떠한 제약을 줄 수도 있었음

(T의 타입은 Equatable을 준수하고 있어야 한다는!)

그리고 실제 내부에서 이게 당장은 무슨 타입인진 모르지만,

범용 타입 파라미터인 T를 사용해서 개발하면 됐었음!!!

 

근데 그럼 만약 프로토콜에서도 제네릭을 사용하고 싶음!!! 

그러면 위처럼 똑같이 <>와 타입 파라미터를 이용해서 선언해주면 될까?

 

 

protocol Stack<T: Equatable> {         // error! An associated type named 'T' must be declared in the protocol 'Stack' or a protocol it inherits
    func push(value: T)
    func pop() -> T
}

 

 

안~ 대~ 용~

Protocol에서 위처럼 Generic을 사용하고 싶다면 associatedtype이란 것을 사용해야 함!!

 

 

 

 

2. associatedtype : Protocol에서 Generic을 사용하는 방법

 

Protocol에서 Generic을 사용하고 싶을 경우,

이때는 associatedtype이란 것을 사용하면 됨!!

 

 

protocol Stack {
    associatedtype value
    
    func push(value: value)
    func pop() -> value
}

 

 

이렇게 프로톹콜 내부에 associatedtype을 쓰고

protocol 내부에서 사용할 범용 타입의 이름을 선언해주면 됨!!!

그러면 기존에 사용했던 방식처럼,

value라는 이름으로 범용 타입으로 사용할 수 있음!!!

 

만약, 타입에 제한을 주고 싶다면 당연히,

 

 

protocol Stack {
    associatedtype value: Equatable
    
    func push(value: value)
    func pop() -> value
}

 

 

이렇게 제약 주는 것도 가능함!! :)

 

 

 

 

3. 채택하는 곳에서 associatedtype이 선언된 제네릭 프로토콜을 쓸 때면..

 

제네릭의 경우, 실제 사용하는 곳에서 타입이 정해진다는 게 특징이잖음?

따라서 이 associatedtype이 선언된 제네릭 프로토콜의 경우,

실제 이 프로토콜을 채택하는 곳에서

 

 

struct VStackStack {
    typealias value = Int
    
    func push(value: value) { }
    func pop() -> value { ... }
}

 

 

이렇게 typealias를 이용해서,

associatedtype을 나는 이런 이런 타입으로 사용할 것이야! 하고 명시해주는 게 일반적임!!!

 

근데 만약, 아래와 같이

 

 

struct VStackStack {
    func push(value: Int) { }
    func pop() -> Int { ... }
}

 

 

typealias 없이도 어떤 타입인지 위처럼 충분히 추론이 가능할 경우,

이때는 typealias를 생략해도 됨!!!

(보통은 위처럼 추론이 가능하게끔 하고, typealias는 생략한다구 함)

 

 

 

4. 놀랍게도! protocol에 기존 방식으로 제네릭 함수를 선언할 수 있습니당!

 

 

protocol Stack {
    func push<T: Equatable>(value: T)
}
 

 

 

associatedtype 때문에 기존 제네릭을 아예 사용 못하는 것 같아 보이지만,

이렇게 메서드를 선언할 때는 제네릭을 사용하는 것이 가능함!!

 

 

 

 

 

 

 

 

 

 

 

.

.

.

망했다 분량조절 대실패다(챕터 나누기 땜시..)

5편에서 7편으로 늘어날 예정^^;;;;

오늘은 Protocol에서의 Generic에 대해 알아봤습니당....

잘못된 내용이나 오타 및 피드백은 댓글로 주세요!! 대환영입니다!!



Calendar
«   2024/04   »
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
최근 댓글
Visits
Today
Yesterday