관리 메뉴

나만을 위한 블로그

[Kotlin] enum 사용 시 values() 대신 entries를 써라? 본문

개인 공부/Kotlin

[Kotlin] enum 사용 시 values() 대신 entries를 써라?

참깨빵위에참깨빵 2023. 7. 19. 22:06
728x90
반응형

미디엄을 돌아다니다가 7월 10일에 올라온 포스팅을 발견했다.

 

https://medium.com/teknasyon-engineering/kotlin-enums-replace-values-with-entries-bbc91caffb2a

 

Kotlin Enums — Replace values() With entries

Make use of Kotlin 1.9.0 updates to improve performance…

engineering.teknasyon.com

 

이 글의 핵심은 코틀린 1.9.0을 사용할 경우, enum을 쓴다면 value() 대신 entries를 사용하라는 것이다.

진짠가 싶어서 구글링해보니 이것과 관련된 내용의 코틀린 공식문서를 찾았다.

 

https://kotlinlang.org/docs/enum-classes.html

 

Enum classes | Kotlin

 

kotlinlang.org

(중략)...코틀린 1.9.0에선 values()를 대체하는 entries 프로퍼티가 도입됐다. 이것은 미리 할당된 enum 상수의 불변 리스트를 반환한다. 이는 컬렉션으로 작업 시 유용하며 성능 문제를 방지하는 데 도움이 될 수 있다.

 

아래는 관련 깃허브다.

 

https://github.com/Kotlin/KEEP/blob/master/proposals/enum-entries.md#examples-of-performance-issues

지원 중단 없이 IDE 지원으로 Enum.values()를 폐기(decommision)한다. 모든 enum 항목의 불변 리스트를 리턴하는 EnumEntries<E> 프로퍼티를 소개한다. 이미 컴파일된 코틀린 enum 및 자바 enum은 사전 할당된 entries 리스트가 포함된 특수 매핑 클래스가 생성된다
코틀린의 표준 폐기 주기를 사용해서 values()를 폐기하면 기존에 존재하던 많은 교육 자료가 시대에 뒤떨어진다. 이를 방지하기 위해 values()는 IDE 지원을 통해 폐기된다

- 값의 우선 순위가 낮아지고 IDE 자동완성에서 제거됨
- values()에 대한 호출을 entries에 대한 호출로 대체하라는 경고가 도입됨
- 코틀린 가이드, J2K 및 자습서 같은 모든 해당 자료는 entries API를 사용하도록 조정됨
- 결과적으로 values() API의 추가 지원 중단을 결정할 것

 

1.9.0부터 적용되는 내용이지만 알고 있어서 나쁠 건 없다. 언젠가 1.9.0 이상의 버전을 써야 하는 때가 올 수 있으니 entries와 values는 뭐가 다른지 확인한다.

아래는 코틀린에서 enum의 값들에 values()를 사용할 경우의 예시다.

 

fun main() {
    RGB.printAllRGB()
}

enum class RGB {
    RED, GREEN, BLUE;

    companion object {
        fun printAllRGB() = values().forEach { println("RGB 값 출력 : ${it.name}") }
    }
}

// RGB 값 출력 : RED
// RGB 값 출력 : GREEN
// RGB 값 출력 : BLUE

 

여기서 values()의 문제점은 크게 3가지다.

 

  • values()를 호출할 때마다 배열을 할당, 복제하기 때문에 성능 이슈의 원인이 된다
  • 기본적으로 변경 가능하고(mutable) 사용자가 수동으로 배열을 리스트로 바꾸게 하는 컬렉션보다 덜 유연한 Array<E>를 리턴함
  • Array<E>를 리턴하기 때문에 enum에 대한 확장 함수 작성이 어렵다

 

그래서 위 코드를 entries를 적용해 수정한다면 아래처럼 리팩토링할 수 있다. 아래 코드는 코틀린 공식문서에서 가져온 예시다. 내 컴퓨터의 인텔리제이에서 코틀린 버전을 1.9.0으로 업그레이드해서 실행시켜보려 했지만 entries 참조를 찾을 수 없다고 계속 표시되어 공식문서 코드를 가져왔다.

 

enum class RGB { RED, GREEN, BLUE }

fun main() {
    for (color in RGB.entries) println(color.toString())
}

 

아래는 미디엄 포스팅의 코드다. 확장 함수 예시도 같이 있다.

 

fun <E : Enum<E>> EnumEntries<E>.someExtension(): E {...}

enum class RGB {
    RED, YELLOW, ....
}

val x: RGB = RGB.entries.someExtension()

 

반응형
Comments