Swift

제네릭

GREEN.1229 2020. 12. 13. 16:54

안녕하세요. 그린입니다!

이번 포스팅에서는 제네릭에 대해 알아보겠습니다.

제네릭은 스위프트 언어로 사용 할 수 있는 아주 중요한 기능입니다..!!

제네릭을 이용하면 코드의 중복을 줄여주고 구현한 기능/타입을 재사용할 수 있습니다 (한번만 구현하면 됩니다~!!)

 

1. 제네릭 선언 및 사용

-. 메서드 이름 뒤 (<>) 기호를 붙여 표시

 -> func generic<T> (value: T) -> T { }

func ++<T: BinaryInteger> (frontNumber: T, backNumber: T) -> T {
	return frontNumber + backNumber
}

* BinaryInteger 프로토콜로 타입을 좀 더 명확히 주어 정수 타입 모두 해당 될 수 있도록 설정

 

2. 제네릭 함수

-. 함수 메서드를 제네릭으로 선언하면 위에서 T가 플레이스홀더로 사용되기에 T의 실제 타입을 컴파일러가 신경쓰지 않습니다.

-. T는 타입 매개변수의 종류

-. T,U,V 등의 대문자 한글자로 표현할때가 많습니다.

 

3. 제네릭 타입

-. <T> 대신 좀 더 명확히 어떤 타입을 사용할지 명시해줄 때는 <Double>, <String> 등 <Type>으로 선언합니다.

struct Stack<Element> {
// 코드 구현부
}

var doubleType: Stack<Double> = Stack<Double>()
var stringType: Stack<String> = Stack<String>() 

* 위와 같이 여러 인스턴스 생성 시 다른 타입으로 생성이 가능합니다.

 

4. 제네릭 타입 확장

-. 기존 제네릭을 정의하면서 붙인 타입 매개변수를 확장하여 사용할 수 있습니다. (extension)

extension Stack {
//추가 기능 구현부
}

*위와 같이 해당 제네릭으로 선언된 메서드의 추가 기능 구현이 가능합니다.

 

5. 타입 제약

-. 타입 제약이란 타입 매개변수가 가져야 할 제약사항을 지정하는 방법입니다.

-. 타입 제약은 상속이 되는 클래스 및 프로토콜 타입으로만 줄 수 있습니다.

-. 여러 제약을 추가할때는 where 절을 사용할 수 있습니다.

-. 연산 시 타입 매개변수 <T> 타입을 <T: BinaryInteger>로 하여 BinaryInteger 프로토콜을 준수하는 타입으로 주어

   연산이 가능하게 할 수 있습니다.

-. 타입 매개변수마다 제약조건을 다르게 하여 구현할 수 도 있습니다.

func ++<T: BinaryInteger>(frontNumber: T, backNumber: T) {
//코드 구현
}

 

6. 프로토콜의 연관 타입

-. 프로토콜 정의 시 연관 타입(Associated Type)을 함께 정의하여 좀 더 유연하게 사용

protocol AssociatedType {
    associatetype ItemType
    var count: Int {get}
    mutating func append(item: ItemType)
}

* 존재하지 않던 ItemType을 연관 타입으로 정의하여 활용

 

7. 제네릭 서브스크립트

-. 서브스크립트도 제네릭을 활용하여 타입을 구현할 수 있습니다.

 

이렇게 간단하게 제네릭에 대한 학습을 해보았습니다. 제네릭을 잘 활용한다면 추후 유연성있는 코드가 될 수 있습니다.

하나의 기능을 다양한 타입마다 새로 선언해주지 않아도 됨으로 더욱 클린한 코드와 확장성에도 좋을것입니다.

다소 복잡한 개념이더라도 한번 이해하고 넘어간다면 좋은 개념입니다..!

감사합니다 :D

 

p.s. 추가로, 해당 제네릭에 대한 학습이나 이해는 "스위프트 프로그래밍 3판 - 야곰 지음"을 참고하였습니다.