이펙티브 코틀린 Item 37: 데이터 집합 표현에 data 한정자를 사용하라

woga·2023년 10월 7일
0

코틀린 공부

목록 보기
40/54
post-thumbnail

데이터 클래스

데이터를 한꺼번에 전달해야 할 때 data class를 쓰는데, class 앞에 data 한정자를 붙이면 몇 가지 함수가 자동으로 생성된다.

  • toString
  • equals와 hashCode
  • copy
  • compoentN(compoent1, component 2 등)

toString 함수는 클래스의 이름과 기본 생성자 형태로 모든 프로퍼티와 값을 출력해준다. 그래서 로그를 출력할 때나 디버그할 때 유용하다.

equals는 기본 생성자의 프로퍼티가 같은지 확인해준다. hashCode도 같은 결과를 낸다.

copy는 기본 생성자 프로퍼티가 같은 새로운 객체를 복제한다.

copy메서드는 data 한정자를 붙이기만 하면 자동으로 만들어져서 구현을 볼수도 볼필요도 없는데 대충 다음과 같을 것이다

fun copy(
	id: Int = this.id,
    name: String = this.name,
    points: Int = this.points
) = User(id, name, points)

copy 메서드는 객체를 얕은 복사하지만 이것은 객체가 immutable이라면 상관없다. 어차피 immutable 객체는 깊은 복사한 객체가 필요 없기 때문이다.

componentN 함수는 위치를 기반으로 객체를 해제한다.

val User = User(1, "Tom", 3452)
val (id, name, points) = user

componentN 함수만 있다면 List와 Map.Entry 등의 원하는 형태로도 객체를 해제할 수 있다.
하지만 위치를 잘못 지정하면 다양한 문제가 발생할 수 있어 위험하다.

그래서 데이터 클래스의 기본 생성자에 붙어 있는 프로퍼티 이름과 같은 이름을 사용하자.

참고로 값을 하나만 갖는 데이터클래스는 해제하지 않는 것이 좋다. 읽는 사람에게 혼동을 줄 수 있기 때문이다. 특히 람다 표현식에서 그렇다

ex)

data class user(val name: String)

fun main() {
	val user = User("Tom")
    user.let { a -> print(a) } // User(name=Tom)
    
    //don't do that
    user.let { (a) -> print(a) } // Tom
}

일부 프로그래밍 언어에서는 아규먼트 주변에 괄호를 입력해도 되거나 하지 않아도 되므로 문제다.

튜플 대신 데이터 클래스 사용하자

데이터 클래스는 튜플보다 많은 것을 제공한다. 코틀린의 튜플은 Serializable을 기반으로 만들어지며 toString을 사용할 수 있는 제네릭 데이터 클래스다.

현재 코틀린에는 Pair, Triple 2개의 튜플만 남아있다.

튜플은 좋아보였지만 어떤 타입을 나타내는지 예측할 수 없었기 때문에 데이터를 사용하는 것이 선호되었고 점차 없어지게 됐다.

위의 2개는 몇 가지 목적으로 인해 남아 있다.

  • 값에 간단하게 이름을 붙일 때
val (desc, color) = when {
	degrees < 5 -> "cold" to Color.BLUE
    else -> "hot" to Color.Red
}
  • 표준 라이브러리에서 볼 수 있는 것처럼 미리 알 수 없는 집합을 표현할 때
val (odd, even) = numbers.partition { it % 2 == 1 }
val map = mapOf(1 to "San Francisco", 2 to "Amsterdam")

이를 제외하면 무조건 데이터 클래스를 사용하는 것이 좋다.

데이터 클래스를 사용하면,

  • 함수의 리턴 타입 명확
  • 리턴 타입이 더 짧아지며 전달하기 쉽다.
  • 사용자가 데이터 클래스에 적혀 있는 것과 다른 이름을 활용해 변수를 해제하면 경고 출력

이 클래스가 좁은 스콥을 갖게 하고 싶으면 private을 붙여 가시성에 제한을 걸면 된다.

코틀린에서 클래스는 큰 비용없이 사용할 수 있는 좋은 도구다. 따라서 클래스를 활용하는데 두려움을 갖지 말고, 적극적으로 활용하자

profile
와니와니와니와니 당근당근

0개의 댓글