밤에 쓴 코드

Swift ) 제네릭 본문

Swift

Swift ) 제네릭

붱이🦉 2019. 6. 17. 17:11

제네릭


제네릭은 일종의 자리맡기 타입 (place holder) 을 이용한 구현이다

배열과 딕셔너리 같이 많은 어떤 특정 조건만 준수하면 어떤 타입이든 수용할 수 있는 구조체들이 존재한다.

Generic을 한국어로 표현하면 포괄적인,일반적인 이라고 표현됨을 인지하고

프로그래밍에서의 Generic을 이해해보자

일단 제네릭표현법을 코드로 작성해보겠다.

이전에 사용자정의 연산자를 인용하여 진행한다.

infix operator <->

func <->(lhs: inout Int, rhs: inout Int) {
  let temp = lhs
  lhs = rhs
  rhs = temp
}

위와 같이 서로를 바꾸는 연산자를 구현했다.

var a: Int = 1
var b: Int = 2
print("a: \(a) , b: \(b)")    //    a: 1 , b: 2
a <-> b
print("a: \(num1) , b: \(num2)")    //    a: 2 , b: 1

이렇게 바뀌는 모습을 볼수 있다.

하지만 다른 타입에 대해서는 적용이 되지 않을 것이다.

스크린샷 2019-06-17 오후 4 43 55

그래서 구현을 해볼것이다

func <->(lhs: inout String, rhs: inout String) {
  let temp = lhs
  lhs = rhs
  rhs = temp
}

똑같이 생겼는데 타입만 변경 되었다.

코드가 중복되는게 보인다. Double,Float등 많은 타입에서 <->같은 연산자를 사용하려면 각각 구현해주어야 겠다.

그런데 한번 규칙을 보자

저 코드에서

func <->(lhs: inout ⬜️, rhs: inout ⬜️) {
  let temp = lhs
  lhs = rhs
  rhs = temp
}

⬜️ 가 중복되고있다 .

저 위치에 들어가는 아이들을 유연하게 확장하기 위해서 이런 시도를 해볼 수 있다.

func <->(lhs: inout Any, rhs: inout Any) {
  let temp = lhs
  lhs = rhs
  rhs = temp
}

제법 괜찮아보인다.

하지만 문제가 생긴다

var a: Int = 1
var b: String = "Hello"
a <-> b

우리가 의도한 바는 이런 상황에는 오류를 뱉기를 원할 것이다.

다시 정리해보면 lhs , rhs 에 아무 타입이나 오는 것이 아니라 두개의 같은 타입 이라는 제약이 존재한다.

그걸 코드로 표현할 수 있다.

func <-><T>(lhs: inout T, rhs: inout T) {
  let temp = lhs
  lhs = rhs
  rhs = temp
}

<T>는 T가 구체적인 타입이 아니라 자리맡기(placeholder)타입이라는걸 알려줄 뿐이다.

struct T {}

이런게 존재할 지 모르는거니까 < >로 이건 특정 타입이 아닌 자리맡기 타입 표현이다.

둘이 타입만 맞으면 저 연산자의 인터페이스에 일치하므로 연산을 하는데 어려움이 없어진다.

이제 우리가 흔히 사용하는 Dictionary 타입을 파해쳐 볼 것이다.

스크린샷 2019-06-17 오후 5 06 49

딕셔너리의 구현부이다.

딕셔너리는 두개의 자리맡기 타입(Key, Value )을 이용하고 있고, 이중 앞에 오는 타입은 꼭 Hashable 프로토콜을 준수해야한다고 명시해두는 것이다.

그래서 우리가 사용하는 딕셔너리는 [String:String], [Int: String] , [Double: String]등의 다양한 형태에 대해 모두 구현되어 있는게 아니라 제네릭으로 구현되어있다는 것을 잘 보여주는 예이다.

'Swift' 카테고리의 다른 글

Swifty Tips ⚡️  (0) 2019.10.24
Swift) 사용자 정의 연산자  (0) 2019.06.17
Swift) Closure - 클로저  (0) 2019.05.08
Swift) POP - Protocol Oriented Programming  (1) 2019.04.25
Swift) Extension - 익스텐션  (0) 2019.04.25
Comments