데이터를 한꺼번에 전달해야 하는 경우 다음과 같은 클래스를 사용한다.
data class Player(
val id: Int,
val name: String,
val points: Int
)
data 한정자를 붙이면 아래와 같은 몇가지 함수가 자동으로 생성된다.
- toString
- equals와 hashCode
-
copy
- copy는 immutable 데이터 클래스를 만들 때 편리하게 활용할 수 있다. copy는 객체를 얕은 복사 한다.
-
componentN
-
위치를 기반으로 객체를 해제할 수 있다. 위치를 잘못 지정하면 큰 문제가 발생할 수 있으니 주의한다.
val (id, name, pts) = player
-
튜플 대신 데이터 클래스 사용하기
데이터 클래스는 튜플보다 많은 것을 제공한다.
public data class Pair<out A, out B>(
public val first: A,
public val second: B
) : Serializable {
/**
* Returns string representation of the [Pair] including its [first] and [second] values.
*/
public override fun toString(): String = "($first, $second)"
}
public data class Triple<out A, out B, out C>(
public val first: A,
public val second: B,
public val third: C
) : Serializable {
/**
* Returns string representation of the [Triple] including its [first], [second] and [third] values.
*/
public override fun toString(): String = "($first, $second, $third)"
}
코틀린에 남아있는 튜플은 Pair와 Triple이 전부이다. 튜플은 좋아 보이지만 데이터 클래스를 사용하는것이 더 좋기 때문에 점차 없어졌다. 이는 몇가지 지역적인 목적으로 남아있다.
-
값에 간단하게 이름을 붙일 때
val (description, color) = when { degrees < 5 -> "cold" to Color.BLUE degrees < 23 -> "mild" to Color.YELLOW else -> "hot" to COLOR.RED }
-
표준 라이브러리에서 볼 수 있는 것 처럼 미리 알 수 없는 aggregate(집합)을 표현할 때
val (odd, even) = numbers.partition { it % 2 == 1 } val map = mapOf(1 to "San Francisco", 2 to "Amsterdam")
위 경우를 제외하면 데이터 클래스를 사용하는게 좋다.
예를 들어 fullname과 name을 나타내는 코드를 정의할 때 Pair<String, String>
을 사용하면 해당 Pair가 전체 이름을 나타내는것을 인지하기 어렵다.
이를 데이터 클래스로 만들어도 큰 추가 비용이 들지 않으며 다음과 같은 장점이 있다.
- 함수의 리턴 타입이 더 명확해진다.
- 리턴 타입이 더 짧아지며 전달하기 쉬워진다.
- 사용자가 데이터 클래스에 적혀있는 것과 다른 이름을 활용해 변수를 해제하면, 경고를 출력한다.
Reference
- 이펙티브 코틀린 - 프로그래밍 인사이트, 마르친 모스칼라 지음, 윤인성 옮김
개인적인 기록을 위해 작성된 글이라 잘못된 내용이 있을 수 있습니다.
오류가 있다면 댓글을 남겨주세요.