구문 영역(lexical scope)에 따른 변수 가시성 규칙이 지역 클래스 안의 내포된 클래스에서만 동작하지 않으면 얼핏 혼동을 야기하기 쉽다.
Lexical Scope는 "변수의 유효 범위(Scope)는 코드를 작성한 구조에 따라 결정된다"는 규칙입니다.
fun outerFunction() {
val outerVar = 10 // outerFunction의 영역
fun innerFunction() {
val innerVar = 20 // innerFunction의 영역
println(outerVar) // ✅ innerFunction 안에서 outerVar 접근 가능!
println(innerVar) // ✅ innerVar도 접근 가능
}
innerFunction()
// println(innerVar) // ❌ 에러! outerFunction에서 innerVar 접근 불가능!
}
위 코드에서 innerFunction
은 outerFunction
안에 작성되었습니다. 이게 바로 구문 영역입니다. innerFunction
은 outerFunction
의 "자식" 또는 "내부" 영역에 있다고 볼 수 있죠.
innerFunction
(안쪽)은 outerFunction
(바깥쪽)의 outerVar
에 접근할 수 있습니다.outerFunction
(바깥쪽)은 innerFunction
(안쪽)의 innerVar
에 직접 접근할 수 없습니다.이것이 우리가 코드를 읽고 이해할 때 자연스럽게 기대하는 방식입니다. 코드가 중첩되어 있으면, 안쪽 코드는 바깥쪽 코드에 선언된 변수들을 "알고 있을" 것이라고 예상하죠.
이제 원래 문장으로 돌아가 봅시다:
"구문 영역(lexical scope)에 따른 변수 가시성 규칙이 지역 클래스 안의 내포된 클래스에서만 동작하지 않으면 얼핏 혼동을 야기하기 쉽다."
이 문장은 다음과 같은 상황을 경고하는 것입니다.
args
)에 접근할 수 있습니다. (이것은 구문 영역 규칙을 따르는 자연스러운 행동입니다.)fun main(args: Array<String>) {
class LocalFoo { // 지역 클래스
val length = args.size // ✅ LocalFoo는 main의 args에 접근 가능 (자연스러움)
}
}
inner
가 아닌 경우): 클래스 안에 또 다른 클래스가 있지만, 바깥 클래스와 독립적입니다. 기본적으로 바깥 클래스의 멤버(변수, 함수 등)에 직접 접근할 수 없습니다.