Scope
코딩에서의 대원칙 : 중괄호 내애서 밖의 변수는 접근 가능, 중괄호 밖에서 중괄호 내의 변수는 접근 불가능
- Scope(스코프)는 변수나 함수가 유효한 범위를 의미한다
- 즉, 어디에서 변수를 사용할 수 있고, 어디에서 사용할 수 없는지를 결정하는 규칙이다
- Swift에서는 스코프가 다른 곳에서는 특정 변수나 함수에 접근할 수 없도록 제한하기 때문에 변수의 충돌을 방지하고, 코드의 가독성과 유지보수성을 높여준다
Swift의 스코프 종류
- Swift의 스코프는 크게 4가지로 나눌 수 있다
| 스코프 종류 | 설명 |
|---|
| 전역 스코프(Global Scope) | 프로그램 전체에서 접근할 수 있는 범위 |
| 함수 스코프(Function Scope) | 함수 내부에서만 접근할 수 있는 범위 |
| 블록(제어문) 스코프(Block Scope) | if, for, while 등 블록 내부에서만 유효 |
| 클래스 / 구조체 스코프(Type Scope) | 클래스나 구조체 내부에서 유효 |
전역 스코프(Global Scope)
- 전역 스코프는 프로그램 어디에서나 접근할 수 있는 변수와 함수를 의미한다
- 전역 변수(Global Variable)와 전역 함수(Global Function)는 모든 범위에서 접근이 가능하지만, 너무 많이 사용하면 메모리를 많이 차지하고, 프로그램의 복잡도가 증가할 위험이 있다
var globalVar = "나는 전역 변수"
func globalFunction() {
print(globalVar)
}
globalFunction()
func anotherFunction() {
print("다른 함수에서도 \(globalVar)를 사용할 수 있음")
}
anotherFunction()
나는 전역 변수
다른 함수에서도 나는 전역 변수를 사용할 수 있음
globalVar 변수는 전역 스코프에 정의되어있기 때문에 어디서든 접근 가능
- 전역 함수에서도 자유롭게 사용 가능
⚠️ 전역 변수는 주의해서 사용해야 한다
- 너무 많이 사용하면 메모리를 계속 차지하고, 변경될 위험이 커진다
globalVar 값이 프로그램 어디서든 바뀔 수 있어, 예상치 못한 버그를 만들 수 있다
함수 스코프(Function Scope)
- 함수 내부에서 선언된 변수는 함수 내부에서만 접근 가능하고, 함수가 끝나면 변수도 사라진다
func localFunction() {
let localVar = "나는 지역 변수"
print(localVar)
}
localFunction()
localVar 변수는 localFunction() 내부에서만 유효
- 함수가 끝나면
localVar 는 사라지며, 외부에서는 접근 불가능
블록 스코프(Block Scope)
- 제어문(
if, for, while 등) 안에서 선언된 변수는 해당 블록 안에서만 유효하다
블록 내부에서만 접근 가능한 변수
func blockScopeExample() {
if true {
let blockVar = "나는 블록 변수"
print(blockVar)
}
}
blockScopeExample()
blockVar 변수는 if 블록 내부에서만 유효하고, 블록을 벗어나면 사라진다
반복문에서도 동일하게 적용
func loopScopeExample() {
for i in 1...3 {
let loopVar = "반복문 내부 변수"
print(loopVar)
}
}
loopScopeExample()
loopVar 은 for 반복문 내부에서만 존재하며, 반복문이 끝나면 사라진다
⚠️ 블록 스코프를 주의해야하는 이유
- 블록 내부에서 선언된 변수를 블록 바깥에서 사용하려 하면 오류 발생
- 잘못된 변수 사용으로 인해 버그가 발생할 수도 있음
클래스 / 구조체 스코프(Type Scope)
- 클래스나 구조체 내부에서 선언된 변수는 해당 타입의 인스턴스 내에서만 사용 가능하다
class Person {
var name: String
init(name: String) {
self.name = name
}
func introduce() {
print("안녕하세요, 저는 \(name)입니다.")
}
}
let person = Person(name: "Royce")
person.introduce()
name 은 Person 클래스의 인스턴스 변수로, 객체를 생성해야 접근 가능
스코프의 중첩(Nested Scope)
- 스코프는 안쪽에서 바깥쪽으로는 접근 가능하지만, 바깥쪽에서 안쪽으로는 접근 불가능하다
var globalVar = "전역 변수"
func outerFunction() {
let outerVar = "외부 함수 변수"
func innerFunction() {
let innerVar = "내부 함수 변수"
print(globalVar)
print(outerVar)
print(innerVar)
}
innerFunction()
}
outerFunction()
innerFunction() 내부에서는 모든 스코프(전역, 외부함수, 내부함수)에 접근 가능
outerFunction() 에서는 innerFunction() 내부 벼수인 innerValue 에 접근할 수 없다
클로저(Closure)와 스코프
- Swift의 클로저는 함수의 외부 변수(상위 스코프)에 접근이 가능하다
- 이러한 특징을 클로저 캡처(Closure Capture)라고 한다
func makeIncrementer() -> () -> Int {
var total = 0
let incrementer: () -> Int = {
total += 1
return total
}
return incrementer
}
let increment = makeIncrementer()
print(increment())
print(increment())
print(increment())
total 변수는 원래 makeIncrementer() 함수가 끝나면 사라져야 하지만, 클로저 incrementer 가 total 변수를 캡처하여 계속 유지함
정리
| 스코프 종류 | 설명 |
|---|
| 전역 스코프 | 프로그램 전체에서 접근 가능 |
| 함수 스코프 | 함수 내부에서만 유효 |
| 블록 스코프 | if, for, while 등 특정 블록 내부에서만 유효 |
| 클래스 / 구조체 스코프 | 클래스 또는 구조체 내부에서만 유효 |
| 스코프 중첩 | 내부에서 외부 접근 가능, 외부에서 내부 접근 불가 |