kyucumber
전체 글 보기

이펙티브 코틀린 아이템 02. 변수의 스코프를 최소화하라

상태 정의 시 변수와 프로퍼티의 스코프를 최소화 하는 것이 좋다.

  • 프로퍼티 보다는 지역 변수를 사용한다.
  • 최대한 좁은 스코프를 갖게 변수를 사용한다. 예를 들어 반복문 내부에서만 사용되면 변수를 반복문 내부에 작성하는것이 좋다.

변수는 읽기 전용 전용 여부와 상관 없이 if, when, try-catch, elvis operator 등을 활용해 변수를 정의할 때 초기화되는 것이 좋다.

fun updateWeather(degrees: Int) { val (description, color) = when { degrees < 5 -> "cold to Color.BLUE else -> "hot" to Colodr.RED } }

여러 프로퍼티를 한꺼번에 설정해야 하는 경우 위처럼 destructuring declaration을 활용한다.

캡처링

에라토스테네스의 체 구현 시 아래와 같은 코드를 작성할 수 있다.

val primes: Sequence<Int> = sequence { var numbers = generateSequence(2) { it + 1 } while (true) { val prime = numbers.first() yield(prime) numbers = numbers.drop(1) .filter { it % prime != 0 } } } println(primes.take(10).toList()) // [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

위 코드를 아래와 같이 최적화하려고 시도하는 경우 문제가 발생한다.

val primes: Sequence<Int> = sequence { var numbers = generateSequence(2) { it + 1 } // while 스코프 바깥에 var로 정의 var prime: Int while (true) { prime = numbers.first() yield(prime) numbers = numbers.drop(1) .filter { it % prime != 0 } } } println(primes.take(10).toList()) // [2, 3, 5, 6, 7, 8, 9, 10, 11, 12]

위와 같은 문제가 발생할 수 있으므로 가변성을 피하고 스코프 범위를 좁게 만들어 이런 문제를 간단하게 피해갈 수 있다.

Sequence를 많이 사용해보지 않아 조금 헷갈렸는데, var를 사용할 때 prime 값이 ObjectRef로 캡처링되면서 지연 필터링이 우리가 의도한 대로 동작하지 않는 것 같습니다.

Kotlin Lambda Capture Variable

정리

  • 변수의 스코프는 좁게 만들어서 활용하자.
  • var 보다는 val을 사용하는 것이 좋다.
  • 람다에서 변수를 캡처한다는 것을 기억하자.

Reference

  • 이펙티브 코틀린 - 프로그래밍 인사이트, 마르친 모스칼라 지음, 윤인성 옮김

개인적인 기록을 위해 작성된 글이라 잘못된 내용이 있을 수 있습니다.

오류가 있다면 댓글을 남겨주세요.

Table of contents