[Tistory] 이펙티브 코틀린 1장 아이템2 – 변수의 스코프를 최소화하라

원글 페이지 : 바로가기

아이템2의 주제: 변수의 스코프를 최소화 하는것이 좋다 스코프란? 어떤 요소의 스코프라고 한다면 그 요소를 볼 수 있는 컴퓨터 프로그램 영역이다. 변수의 스코프라고 한다면 그 변수를 인식하고 사용할 수 있는 범위를 의미한다. 코틀린에서는 기본적으로 {} 중괄호로 스코프를 만든다. 상태를 정의할때는 변수와 프로퍼티의 스코프를 최소화 하는 것이 좋다. 프로퍼티 보단 지역변수를 사용하는것이 좋다. 최대한 좁은 스코프를 갖도록 변수를 사용한다. 스코프 범위 좁히기의 예시 // 가장 안좋은 방법
var user: User
for(i in users.indices) {
user= users[i]
print(“user at $i is $user”)
}

// 조금 더 좋은 방법
for(i in users.indices) {
val user = users[i]
print(“user at $i is $user”)
}

// 가장 좋은 방법
for((i, user) in users.withIndex()) {
print(“user at $i is $user”)
} 변수는 정의할때 초기화하는것이 좋다 – if, when, try-catch, Elvis 표현식을 활용하면 변수를 정의할때 초기화하는것이 편해진다. // if
val user: User = if(hasValue) {
getValue()
} else {
User()
}

// when
val dayType = when (val dayOfWeek = “Monday”) {
“Monday”, “Tuesday”, “Wednesday”, “Thursday”, “Friday” -> “Weekday”
“Saturday”, “Sunday” -> “Weekend”
else -> “Invalid day”
}

println(dayType) // 출력: Weekday

// try-catch
val result: Int = try {
// 예외가 발생할 수 있는 코드
val numerator = 10
val denominator = 2
numerator / denominator
} catch (e: ArithmeticException) {
// 예외가 발생한 경우 처리할 코드
println(“ArithmeticException caught: ${e.message}”)
0 // 예외가 발생했을 때 반환할 값
}

println(result) // 출력: 5

// Elvis
val input: String? = null
val result: String = input ?: “Default Value”
println(result) // 출력: Default Value – 여러 프로퍼티를 한번에 설정할때는 구조분해선언을 활용하는것이 좋다 fun updateWeather(degrees: Int) {
val (description, color) = when {
degrees < 5 -> “cold” to Color.BLUE
degrees < 23 -> “mild” to Color.YELLOW
else -> “hot” to Color.RED
}

} 캡처링 캡처링이 뭘까요? 캡처링(=람다 캡처링): 람다 블럭 외부에서 정의된 변수를 참조하는것 람다식: 다른 함수에 매개변수로 넘길수있는 함수, 중괄호로 묶인다 fun printMessageWithPrefix(messages: Collection, prefix: String) {

var clientErrors = 0
var serverErrors = 0

messages.forEach {
if(it.startsWith(“4”)) {
clientErrors++ //lamda capture
}else if(it.startsWith(“5”) {
serverErrors++ //lamda capture
}
}

println(“$clientErrors client errors, $serverErrors server errors”)
} 하지만 이런 캡처링때문에 문제가 생길 수 있다 아래는 소수를 구하는 코틀린 코드이다 fun runWithSequenceBuilder() {
val primes: Sequence = sequence {
var numbers = generateSequence(2) { it + 1 }
while (true) {
val prime = numbers.first()
yield(prime) // sequence에 prime을 넘겨준다.
numbers = numbers.drop(1)
.filter { it % prime != 0 }// prime의 배수를 필터링
}
}
println(primes.take(25).toList()) // sequence에 쌓인것중 25개를 List로 변환한다.
}
//[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97] 이렇게 코드를 작성하면 정상 작동한다 하지만 prime 변수를 while 밖으로 빼면 어떻게 될까 fun runWithSequenceBuilderButWrongScope() {
val primes: Sequence = sequence {
var numbers = generateSequence(2) { it + 1 }
var prime: Int
while (true) {
prime = numbers.first()
yield(prime)
numbers = numbers.drop(1)
.filter { it % prime != 0 }
}
}
println(primes.take(25).toList())
}
//[2, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27] prime 의 선언을 var로 하고 while문 밖에 선언했다 그러면 var 이니깐 while돌면서 prime값이 바뀌면서~ 잘 돌아가겠징? 하지만 아님 시퀀스는 게으른 연산(lazy evaluation)을 사용한다. 위 코드에서 primes 는 시퀀스로 만들어져 있다 filter, drop과 같은 중간 연산에서는 바로 연산을 수행하지 않고 종단 연산인 first를 만날때까지 연산을 누적해서 기다린다. 그래서 1번 순환 prime = 2 filter 대기 drop 대기 2번순환 filter 대기 – 참고한 사이트 https://velog.io/@kartmon61/Effective-Kotlin-%EC%BA%A1%EC%B3%90%EB%A7%81capturing%EC%9D%B4%EB%9E%80 Effective Kotlin – 캡쳐링(capturing)이란? 아이템 2: 변수의 스코프를 최소화하라에서 나온 내용람다 또는 익명 함수와 같은 클로저가 외부 스코프에 있는 변수를 포착하고 이를 내부에서 사용할 수 있는 기능을 말한다. 이로 인해 특정 velog.io https://velog.io/@evergreen_tree/Kotlin-%EC%BD%94%ED%8B%80%EB%A6%B0%EC%9D%80-%EB%9E%8C%EB%8B%A4%EC%8B%9D%EC%97%90%EC%84%9C-%EC%99%B8%EB%B6%80-%EB%B3%80%EC%88%98%EB%A5%BC-%EC%96%B4%EB%96%BB%EA%B2%8C-%EC%B0%B8%EC%A1%B0%ED%95%A0%EA%B9%8C [Kotlin] 코틀린은 람다식에서 외부 변수를 어떻게 참조할까? [람다 캡쳐링] [Lambda Capturing] 람다식 내에서 외부 변수를 변경하는 것에 대해 아무런 의문을 느끼지 않다가, 문득 궁금증이 생겼습니다. 함수를 작성하는 시점에는 람다식의 블럭 내부가 실행되지 않다가, 호출되는 시점에 velog.io https://lovia98.github.io/blog/kotlin-lamda.html 코틀린에서의 람다 문법과 사용법 Write an awesome description for your new site here. You can edit this line in _config.yml. It will appear in your document head meta (for Google search results) and in your feed.xml site description. lovia98.github.io https://bottom-to-top.tistory.com/64 아이템 2 – 변수의 스코프를 최소화하라 가시성 제한 상태를 정의할 때는 변수와 프로퍼티의 스코프를 최소화하는 것이 좋다. 프로프티보다 지역 변수를 사용하는 것이 좋다. 최대한 스코프를 좁게 가지도록 변수를 사용하자. 사용되 bottom-to-top.tistory.com https://iosroid.tistory.com/79 코틀린(Kotlin) Collections : 시퀀스(sequences) 코틀린(kotlin) 의 시퀀스(sequence) 를 살펴보자. 원문 https://kotlinlang.org/docs/reference/sequences.html 을 보며 정리. kotlin standard library 는 collection 과 함께 또다른 container type 인 sequences (Sequence) 를 가지고 있 iosroid.tistory.com

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다