출처

이 글은 "Young Kim" 님의 글을 참고하여 작성한 글 임을 미리 밝힙니다

Young Kim 님의 글


get 과 set

예시를 통한 설명

var myProperty: Int {
    get {
        return myProperty
        }
        set(newValue) {
            myProperty = newValue
        }
    }
    
    print(myProperty) // myProperty 출력
    myProperty = 123 // newValue 값은 123
위의 예시를 보고 내가 처음 든 생각은 get은 가지고 있는 값을 돌려주는것이고

set은 어떤 새로운 값을 넣어주는것이다

라고 생각이 들었다.

get, set을 사용하려면 ??

위의 예시처럼 사용하게 되면 안된다.

그 이유는 재귀적으로 자기 자신의 get, set을 호출하기 때문이다

get, set을 사용하려면 실제 값을 저장 할 저장공간이 따로 필요하다

예시를 통한 설명

var storageOfMyProperty: Int

var myProperty: Int {
    get {
        return storageOfMyProperty
    }
    set(newValue) {
        storageOfMyProperty = newValue
    }
}   
"storageOfMyProperty" 는 실제로 값이 저장되는 변수이다

외부에서 myProperty의 값에 접근하거나 새로운 값을 할당하면 실제로 값이 저장되는 곳은

"storageOfMyProperty"이다.

get과 set의 활용

1. 프로퍼티에 값이 할당 될 때 적절한 값인지 검증

class Company {
    var storageOfMembers: Int = 5
    
    var members: Int {
        get {
            return storageOfMembers
        }
        set(newValue) {
            if (newValue < 1) {
                print("직원수는 한명보다 작을 수 없다")
            } else {
                storageOfMembers = newValue
            }
        }
    }
}
Company 클래스 안에 직원수를 나태내는 members 프로퍼티가 있다

직원수는 음수가 될 수 없으므로 members 값을 바꿀 때는 검증 할 필요가 있다

set의 스코프 내에 있는 newValue 값을 사용하여 프로퍼티의 값이 바뀌기 전에

Validation 할 수 있다

2. 다른 프로퍼티 값에 의존적인 프로퍼티를 관리 할 때

class Company {
    var storageOfMembers: Int = 5
    
    var members: Int {
        get {
            return storageOfMembers
        }
        set(newValue) {
            if (newValue < 1) {
                print("직원수는 한명보다 작을 수 없다")
            }else{
                storageOfMembers = newValue
            }
        }
    }
    
    var teamDinnerCost: Int {
        get {
            return storageOfMembers * 100000
        }
    }
}   
회식비인 teamDinnerCost 프로퍼티가 추가 되었는데, 회식비는 직원 수에 비례하기 때문에

storageOfMembers에 의존적이다.

storageOfMembers 프로퍼티에 get을 사용하면 직원수에 비례하여 계산된 회식비를 반환하도록

할 수 있다.

이런 경우에는 teamDinnerCost의 값을 따로 신경쓰지 않아도 된다

또한 get만을 구현했으므로 외부에서 teamDinnerCost의 값을 변경하려고 하면 에러가 발생한다

따라서 회식비는 직원수에 비례하여 정해진 값 만을 반환한다

3. 프로퍼티를 private하게 사용하기 위해

    
private(set) var myProperty: Int = 10
위의 예시와 같은 경우 myProperty는 "internal getter" 와 "private setter"을 얻게된다

myProperty가 선언된 파일내에서만 값을 수정 할 수 있고 외부에서는 값을 수정 할 수 없다

그러나 myProperty의 값을 얻는것은 모듈내 어디서든 가능하다
    
public private(set) var myProperty: Int = 10
위와 같은 경우에는 "internal getter"이 아닌 "public getter"로 선언되었다

위와 같이 선언시 myProperty의 값은 어디서든 접근이 가능하다

다만 이렇게 선언할 경우 class를 public 클래스로 선언 해 주어야 한다.