제네릭

제네릭 문법이 필요한 이유

  • 같은 기능을 하는 함수인데, 매개변수의 타입이 다른경우는 계속 같은 함수를 만들어줘야돼!

    • swap 하는 함수를 만드는데, Int와 Int를 바꾸는 함수, Double과 Double을 바꾸는 함수 등등.. 굉장히 불편 ^^! → 이런 상황들을 위해서 제너릭 문법이 필요한거임

제네릭 필요성

  • 타입만 다르고 구현내용이 동일할 때 사용하는 것

  • 한 번의 구현으로 모든 타입을 커버하는 것

    • 타입과 관계 없이 한 번의 구현으로 모든 타입을 처리하여 유연한 함수, 구조체, 클래스, 열거형 등을 일반화 가능한 코드로 작성한다.

    • 구현 방법

    func printArray**<T>(array: [T])** {
        for number in array {
            print(number)
        }
    }

제네릭 함수의 정의

함수 정의 방법

  1. 타입 파라미터

  • 타입파라미터 ****는 함수 내부에서 파라미터의 타입이나 리턴형으로 사용된다. (함수 바디에서도 사용가능)

  • 타입 파라미터는 관습적으로 T를 사용한다.

    • 다른 문자를 사용해도 된다. (Upper camel case사용해야함)

  • <T, U>, <A, B> 등 타입 파라미터를 2개 이상으로 선언할 수 있다.

    • 서로 다른 타입을 사용해야할 때 사용하는 방법이다.

  1. 제네릭 타입의 extension

  • 타입 파라미터를 명시하지 않고 확장해야한다.

  • 본체의 제네릭에서 정의한 타입 파라미터를 사용할 수 있다.

  • 단 where을 사용하여 특정 타입으로 제한은 가능하다.

나도 모르게 숨어있던 제네릭!

let array = Array**<String>** = ["Cook",  "Musk"]

let dict = Dictionary**<String, Int>** = ["A": 1, "B": 2]

var optional: Optional**<String>** 
  • 실제 사용하고자 할 때에는 T가 정의된 위치에 실제 타입을 넣어주어야한다.

제네릭의 타입 제약

  1. 프로토콜 제약

  • 특정 프로토콜을 따르는 타입으로만 치환할 수 있도록 제약 가능하다

  1. 클래스 타입 제약

  • 특정 클래스와 상속 관계 내에 속하는 클래스만 치환할 수 있도록 제약할 수 있다.

프로토콜에서의 제네릭 문법 사용하는 방법

  1. 연관타입을 지정 방식

  • associatedtype (연관타입) 키워드를 쓰고, 타입 파라미터로 사용할 문자를 작성한다.

    • 프로토콜에서 플레이스 홀더 역할을 한다. (어떤 타입이든 입력되야한다는 것을 제시한다.)

  1. 프로토콜 채택 및 연관 타입 사용 방법

  • typealias를 사용하여 명식적으로 타입을 치환한다. (생략 가능하다)

  • 생략가능하므로, 실 타입을 구현한 함수에서 실제 타입을 사용하기만하면 된다.

Last updated