🔥 전역 변수와 지역 변수

553자
6분

Swift에서 변수는 전역 변수(Global Variables)와 지역 변수(Local Variables)로 나눌 수 있어요. 전역 변수부터 같이 알아볼게요.

전역 변수(Global Variables)

전역 변수는 함수, 메서드, 클로저, 타입 컨텍스트 외부에 정의된 변수를 말해요. 이전 장에서 다뤘던 전역 변수들은 모두 저장 변수(Stored Variables)였죠.

저장 변수는 저장 속성과 마찬가지로 특정 타입의 값을 저장하고, 해당 값을 설정하고 검색할 수 있게 해준답니다.

var globalVar = 10 // 전역 변수 선언 및 초기화
 
func someFunction() {
    print(globalVar) // 10
}
 
someFunction()
print(globalVar) // 10
swift

위 코드에서 globalVar는 전역 변수로 선언되었어요. someFunction() 내부와 외부 모두에서 globalVar에 접근할 수 있죠.

지역 변수(Local Variables)

반면에 지역 변수는 함수, 메서드, 클로저 컨텍스트 내에 정의된 변수예요.

func someFunction() {
    var localVar = 20 // 지역 변수 선언 및 초기화
    print(localVar) // 20
}
 
someFunction()
// print(localVar) // 오류: localVar는 someFunction() 내부에서만 접근 가능
swift

localVarsomeFunction() 내부에서 선언된 지역 변수라서 함수 외부에서는 접근할 수 없어요.

계산 변수(Computed Variables)

그런데 재미있는 사실은, 전역 변수와 지역 변수 모두 계산 변수(Computed Variables)로 정의할 수 있다는 거예요. 계산 변수는 계산 속성처럼 값을 저장하지 않고 계산하죠.

var storedGlobalVar = 10 // 저장 전역 변수
 
var computedGlobalVar: Int { // 연산 전역 변수
    return storedGlobalVar * 2
}
 
func someFunction() {
    var storedLocalVar = 20 // 저장 지역 변수
 
    var computedLocalVar: Int { // 연산 지역 변수
        return storedLocalVar + 5
    }
 
    print(computedLocalVar) // 25
}
 
print(computedGlobalVar) // 20
someFunction()
swift

computedGlobalVar는 전역 범위에서 정의된 계산 변수고, computedLocalVarsomeFunction() 내에서 정의된 연산 지역 변수예요.

속성 래퍼

그리고 지역 저장 변수에는 속성 래퍼(Property Wrapper)를 적용할 수 있어요. 하지만 전역 변수나 계산 변수에는 적용할 수 없답니다.

@propertyWrapper
struct SmallNumber {
    private var value: Int
    var wrappedValue: Int {
        get { return value }
        set { value = min(newValue, 12) }
    }
 
    init() { self.value = 0 }
}
 
func someFunction() {
    @SmallNumber var myNumber: Int = 0 // 지역 변수에 속성 래퍼 적용
 
    myNumber = 10
    print(myNumber) // 10
 
    myNumber = 24
    print(myNumber) // 12
}
 
someFunction()
swift

SmallNumber라는 속성 래퍼를 정의하고, someFunction() 내부의 지역 변수 myNumber에 적용했어요.

속성 래퍼는 wrappedValuesetter에서 새로운 값이 12보다 크면 12로 제한하도록 구현되어 있죠.

따라서 myNumber에 24를 할당하면 12로 저장된답니다. 신기하죠?

함수 매개변수에 속성 래퍼 적용

더 나아가서, 함수의 매개변수에도 속성 래퍼를 적용할 수 있어요. 함수 매개변수는 함수 내부에서 사용되는 일종의 지역 변수로 볼 수 있기 때문이죠.

func printSmallNumber(@SmallNumber num: Int) {
    print(num)
}
 
printSmallNumber(num: 10) // 10
printSmallNumber(num: 24) // 12
swift

printSmallNumber 함수의 매개변수 num@SmallNumber 속성 래퍼를 적용했어요.

함수를 호출할 때 num에 10을 전달하면 그대로 10이 출력되고, 24를 전달하면 속성 래퍼에 의해 12로 제한되어 12가 출력되는 걸 확인할 수 있죠.

이렇게 함수 매개변수에 속성 래퍼를 사용하면 전달받은 값을 원하는 방식으로 가공하거나 제한할 수 있어요.

또한 속성 래퍼를 사용하면 코드의 재사용성도 높일 수 있답니다. 여러 함수에서 동일한 제약사항이 필요한 경우 속성 래퍼를 정의해두고 필요한 매개변수에 적용하면 되니까요.

func calculateSmallNumber(@SmallNumber num1: Int, @SmallNumber num2: Int) {
    let result = num1 + num2
    print(result)
}
 
calculateSmallNumber(num1: 10, num2: 5) // 15
calculateSmallNumber(num1: 20, num2: 8) // 24
swift

calculateSmallNumber 함수의 매개변수 num1num2 모두에 @SmallNumber 속성 래퍼를 적용했어요.

두 번째 호출에서 num1에 20을 전달했지만 속성 래퍼에 의해 12로 제한되고, num2에 전달한 8과 합쳐져 24가 출력되는 걸 볼 수 있죠.

이렇게 Swift에서는 전역 변수와 지역 변수에 대해 다양한 기능을 제공해요. 상황에 맞게 적절한 변수를 선택하고, 속성 래퍼를 활용하면 더욱 효율적이고 가독성 높은 코드를 작성할 수 있습니다.