스코프

같은 이름의 변수가 두 군데에 있으면, 어느 쪽이 쓰일까?

스코프

이름이 보이는 범위

스코프(scope)는 변수를 쓸 수 있는, 다시 말해 변수가 보이는 코드 범위입니다. 함수 안에서 선언한 변수는 그 함수의 지역 변수입니다. 보이기는 하지만 그 안에서 선언하지 않은 변수는 비지역 변수입니다.

예시 코드입니다. 함수 밖에서 선언해 프로그램 전체에서 보이는 전역 변수는 비지역 변수의 한 가지입니다.

정적 스코프

안에서 바깥으로 찾습니다

정적 스코프(static scope)는 코드에 적힌 구조로 스코프를 정합니다. 이름이 나오면 먼저 그 자리의 지역 선언에서 찾고, 없으면 바로 바깥 스코프, 또 없으면 그 바깥으로 넓혀 가며 찾습니다.

자바스크립트로 적은 예시입니다. function은 함수를, var는 변수를 만듭니다. 바로 바깥 스코프를 정적 부모(static parent), 둘러싼 스코프 전부를 정적 조상(static ancestor)이라고 합니다.

블록과 은닉

가까운 이름이 먼 이름을 가립니다

블록(block)은 함수 안에 스코프를 하나 더 만드는 구역이고, C에서는 중괄호로 둘러싼 곳입니다. 블록 안에서 바깥과 같은 이름을 다시 선언하면 안쪽 변수가 바깥 변수를 가립니다. 이것이 은닉(hiding)입니다.

교재의 예입니다. 블록은 ALGOL 60에서 시작됐습니다. Java와 C#은 헷갈리기 쉽다는 이유로 이런 재선언을 금지합니다.

선언 순서

스코프는 선언한 곳부터

C99, C++, Java에서는 변수를 블록 중간에서도 선언할 수 있고, 스코프는 선언한 곳에서 블록 끝까지입니다. for 문 안에서 선언한 변수는 그 for 문 안에서만 보입니다.

예시 코드입니다. C#은 스코프를 블록 전체로 정하지만, 선언보다 앞에서 쓰면 역시 오류입니다.

함수형 언어

let도 스코프를 만듭니다

함수형 언어에는 대부분 let 구조가 있습니다. 앞부분에서 이름에 값을 묶고, 뒷부분에서 그 이름을 씁니다. 이름은 let 구조 안에서만 보입니다.

ML로 적은 예시입니다. let과 in 사이에서 val로 이름을 만들고, in과 end 사이에서 씁니다. 함수형 언어는 1강에서 본, 함수에 값을 넣어 계산하는 언어입니다.

전역 스코프

global이 필요한 때

파이썬에서는 함수 안에서 전역 변수를 읽을 수 있습니다. 하지만 값을 넣으려면 global로 선언해야 합니다. 선언 없이 값을 넣으면 같은 이름의 지역 변수가 새로 생깁니다.

예시 코드입니다. def는 함수를 만들고, 들여 쓴 줄이 함수의 안입니다. PHP는 함수 안에서 전역 변수가 보이지 않아, global 선언이나 $GLOBALS 배열로 꺼냅니다.

다음 편

지금까지는 코드의 구조로 찾았습니다. 부른 순서로 찾는 방법도 있습니다

8편같은 코드, 다른 답 4강 목록