스코프
스코프(scope)란 변수에 접근할 수 있는 범위를 의미합니다. 먼저 파이썬에서는 스코프를 기본적으로 함수 단위로 구분합니다.
실제로는 파이썬은 LEGB 룰이라고 불리는 좀더 복잡한 스코프 규칙을 가지고 있지만, 여기서는 단순화해서 함수 기준으로 설명합니다.
def hello(name: str):
num = 3
print(f"Hello {name}")
if __name__ == '__main__':
my_name = "buzzi"
if True:
print("My name is", my_name)
my_name = "mellon"
hello(my_name)
# print(num) # error
실행 결과
My name is buzzi
Hello mellon
코드 실행 부분을 먼저 보면, my_name
변수에 "buzzi"
라는 문자열을 할당합니다. 그 다음 if
문에서 변수 값을 프린트해보면 "buzzi"가 프린트됩니다. 하지만 그 다음 라인에서 my_name = "mellon"
으로 변수의 값을 바꿔 버렸습니다. 파이썬은 스코프를 함수 단위로만 구분하고 있기 때문에 이제 코드 전체에서 값이 바뀌게 됩니다. 따라서 hello(my_name)
의 출력은 Hello mellon
이 됩니다. 마지막으로 # print(num) # error
를 주석 해제하고 실행해 보면 에러가 발생합니다. hello
함수 안에서 선언된 num
이라는 변수를 프린트하기 때문입니다. 즉, num
의 스코프가 hello
함수이기 때문에 함수 바깥에서 참조할 수 없는 것입니다.
이번에는 러스트의 스코프를 살펴보겠습니다.
fn hello(name: String) { let num = 3; println!("Hello {}", name); } fn main() { let my_name = "buzzi".to_string(); { println!("My name is {}", my_name); let my_name = "mellon"; } hello(my_name); // println!("{}", num); // error }
실행 결과
My name is buzzi
Hello buzzi
러스트에서는 스코프를 중괄호 "{}" 기준으로 구분합니다. 먼저 my_name
변수를 "buzzi"로 할당했습니다. 그 다음, 중괄호 안에서 my_name
을 프린트해보면 "buzzi"가 프린트됩니다. 중괄호 안에서 my_name
을 "mellon"으로 할당하더라도, 중괄호를 벗어나면 중괄호 안에서 선언된 my_name
의 스코프가 끝나게 되므로 중괄호 바깥에서는 my_name
의 값은 원래대로 "buzzi"가 됩니다. 따라서 hello(my_name)
의 실행 결과는 "Hello buzzi"가 됩니다. 파이썬에서와 마찬가지로, hello
안에서 선언된 변수인 num
은 함수 바깥에서 참조할 수 없기 때문에 println!("{}", num);
을 주석 해제한 다음 코드를 실행하면 에러가 발생합니다.
러스트의 스코프는 나중에 배울 소유권 모델과 밀접한 연관이 있기 때문에 중괄호를 기준으로 스코프가 변경된다는 사실을 꼭 기억해 두세요.
러스트의 주석은
//
로 표기합니다.