Swift) Generic

Publishing Date:2020-10-13

배경지식

자바에서 우리는 Generic에 대한 개념을 배운 적 있다. 제네릭이란 이름에서 알 수 있듯이 일반적인 데이터 타입을 말한다. 클래스나 메소드에서 사용할 내부 데이터 타입을 컴파일 시에 미리 지정함으로써 타입 검사나 타입 변환과 같은 번거로운 작업을 생략할 수 있도록 하는 것이다.
이 내용은 배경지식을 위해 추가로 공부하다 알게 된 내용인데, 컴파일 시에 미리 타입을 검사, 변환하기 때문에 컴파일 후에는 코드 내의 모든 제네릭 타입은 제거되어 컴파일된 class 파일에는 어떠한 제네릭 타입도 포함되지 않게 된다고 한다.

제네릭을 사용하는 다른 언어에는 Python, C#, Delphi, Java, Nim, Rust, Swift, TypeScript, .NET 등이 있다. C++에서는 템플릿이라는 이름으로 사용한다.

Generic에 관해 구글링하다 보니, 프로그래밍 문법적인 제네릭 내용이 아니라 Generic Programming에 관한 내용도 있었다. 제네릭 프로그래밍은

데이터 형식에 의존하지 않고, 하나의 값이 여러 다른 데이터 타입들을 가질 수 있는 기술에 중점을 두어 재사용성을 높일 수 있는 프로그래밍 방식 파라미터로 전달될 때 필요한 타입으로 인스턴스화되는 타입으로 알고리즘을 작성하는 프로그래밍 스타일

이라고 한다. 여러가지 유용한 컴포넌트들의 재사용성, 모듈화 등의 증가를 위해 사용한다.

Generic

처음에 제네릭을 공부할 때 헷갈렸던 것이, 미리 내부 데이터 타입을 지정하는 것이 왜 일반적인 데이터 타입이 되냐는 것이었다.
컴파일시에 내부 데이터 타입을 지정한다는 것은 곧 인스턴스화 될 때 내부 데이터 타입이 정해진다는 것이다. 대표적으로 ArrayDictionary를 사용할 때 <> 안에 어떤 타입을 넣는지에 따라 해당 타입을 원소로 가지는 컬렉션을 사용할 수 있다. 이는 ArrayDictionary가 제네릭을 사용하는 제네릭 컬렉션이기 때문이다.
따라서 하나의 제네릭 메소드를 만들어 두면 해당 메소드에 허용되는 타입에 대하여 전부 사용할 수 있기 때문에 일반적 이라고 하는 것이다.

제네릭은 다음과 같이 사용한다.

typeName <T> { }
funcName <T> () { }

제네릭은 Int, String과 같은 실제 타입 이름 대신에 플레이스 홀더를 사용한다. 위 예시에는 알파벳 T를 플레이스 홀더로 사용했다. 플레이스 홀더를 사용할 때는 <> 안에 플레이스 홀더의 이름들을 나열한다.
플레이스 홀더란 타입의 종류를 명시하지 않고 어떤 타입이라는 것을 알려주는 역할을 한다. 즉, 플레이스 홀더의 실제 타입이 결정되지 않은 상태에서 클래스나 메소드를 구현하면 해당 클래스가 인스턴스화되는 순간, 혹은 메소드가 호출되는 순간 해당 플레이스 홀더에 전달된 변수의 타입이 플레이스 홀더의 타입이 된다.

왜 사용하는가?

먼저, 배경 지식에서 언급했듯이 제네릭을 이용해 코드를 구현하면 타입 검사와 같이 불필요한 과정을 생략할 수 있다.
또한, 데이터 타입에 관계없이 유연한 코드를 작성할 수 있다. 이는 코드의 재사용성을 높이고 중복을 줄여 깔끔한 코드를 만들어준다.

Reference

Wikipedia- Generic Programming

Comments