학습
Scala 제네릭 (Generics)
Scala 제네릭 (Generics) — 중급
제네릭 (Generics)
1. 도입 (왜 배워야 하는가)
제네릭은 Scala와 같은 현대 프로그래밍 언어에서 매우 중요한 개념입니다. 제네릭을 사용하면 코드의 재사용성을 높이고, 타입 안정성을 보장할 수 있습니다. 실무에서는 다양한 데이터 타입을 처리해야 하는 경우가 많기 때문에, 제네릭을 활용하지 않으면 코드의 중복이 발생할 수 있으며, 타입 관련 오류가 생길 위험이 있습니다. 제네릭을 모르면 특정 타입에 의존하는 코드를 작성하게 되어, 유지보수나 확장이 어려워질 수 있습니다. 예를 들어, 리스트를 사용하는 경우, 제네릭을 사용하지 않으면 Int, String 등 각기 다른 타입의 리스트를 별도로 구현해야 하는 불편함이 발생합니다.
2. 핵심 개념 설명
제네릭은 클래스나 메서드에서 사용할 데이터 타입을 일반화할 수 있게 해주는 기능입니다. 즉, 특정 타입을 지정하지 않고, 타입 매개변수를 사용하는 것입니다. 이를 통해 다양한 데이터 타입에 대해 동일한 로직을 적용할 수 있습니다.
비유
제네릭을 사용할 때는 마치 다용도 조리기구를 사용하는 것과 같습니다. 여러 재료를 넣어도 잘 조리할 수 있는 조리기구처럼, 제네릭을 사용하면 다양한 타입의 데이터를 처리할 수 있습니다.
관련 용어 정리
| 용어 | 설명 |
|---|---|
| 타입 매개변수 | 제네릭 클래스나 메서드에서 사용되는 변수 |
| 타입 안전성 | 컴파일 타임에 타입 오류를 방지하는 기능 |
3. 기본 코드 예제
다음은 제네릭을 사용한 간단한 클래스 예제입니다.
class Box[T](value: T) {
def getValue: T = value
}
val intBox = new Box(123) // Int 타입의 Box 생성
val stringBox = new Box("Hello") // String 타입의 Box 생성
println(intBox.getValue) // 123
println(stringBox.getValue) // Hello
실행 결과
123
Hello
코드 한 줄씩 동작 설명
class Box[T](value: T): 타입 매개변수T를 가진Box클래스를 정의합니다.value는T타입입니다.def getValue: T = value:getValue메서드는value를 반환합니다.val intBox = new Box(123):Int타입의 값을 가지는Box객체를 생성합니다.val stringBox = new Box("Hello"):String타입의 값을 가지는Box객체를 생성합니다.println(intBox.getValue):intBox의 값을 출력합니다.println(stringBox.getValue):stringBox의 값을 출력합니다.
4. 실전 활용 예제
예제 1: 쇼핑몰 장바구니
쇼핑몰에서 장바구니를 구현할 때, 다양한 타입의 상품을 담을 수 있도록 제네릭을 사용할 수 있습니다.
class ShoppingCart[T] {
private var items: List[T] = List()
def addItem(item: T): Unit = {
items = item :: items
}
def getItems: List[T] = items
}
val cart = new ShoppingCart[String]()
cart.addItem("사과")
cart.addItem("바나나")
println(cart.getItems) // List(바나나, 사과)
예제 2: 데이터베이스 레포지토리
제네릭을 활용하여 여러 타입의 데이터베이스 레포지토리를 만들 수 있습니다.
trait Repository[T] {
def save(item: T): Unit
def find(id: String): Option[T]
}
class UserRepository extends Repository[User] {
private var users: Map[String, User] = Map()
def save(user: User): Unit = {
users += (user.id -> user)
}
def find(id: String): Option[User] = {
users.get(id)
}
}
5. 흔한 실수와 주의사항
실수 1: 타입 매개변수 사용을 잊는 경우
잘못된 코드:
class Box(value: Int) { / ... / }
올바른 코드:
class Box[T](value: T) { / ... / }
실수 2: 타입 안정성 문제
잘못된 코드:
val mixedBox = new Box("Hello")
mixedBox.getValue.asInstanceOf[Int] // Unchecked cast
올바른 코드:
val intBox = new Box(123)
intBox.getValue // 타입에 안전하게 접근