[Swift / Property] Computed Property (연산 프로퍼티)

박준혁 - Niro·2023년 2월 25일
0
post-thumbnail

안녕하세요 Niro 입니다!

첫번째 편인 Store Property ( 저장 프로퍼티 ) 를 잘 보고 오셨나요?

Property 에 대한 두번째 편으로 Computed Property ( 계산 프로퍼티 ) 에 대해 알아볼 예정입니다.

이번에도 Swift 공식문서인 The Swift Programming Language 를 참고하여 작성하였습니다.



🧮 Computed Property 란?

간단하게 Property 를 살펴보자면 클래스, 구조체, 열거형 에서 사용하는 변수나 상수에 관련한 값입니다.

여러가지 Property 중 저장 프로퍼티 는 클래스, 구조체에서 값을 저장하기 위해 사용하는 Property 였습니다.

그럼 Computed Property 는 무엇일까요?

" 클래스, 구조체, 열거형에서 선언할 수 있고 실제 값을 저장하고 있는 것이 아니라 gettersetter 를 통해 값을 탐색하고 간접적으로 다른 프로퍼티 값을 설정할 수 있는 방법을 제공합니다. "

라고 설명이 되어있습니다..

일단 저장 프로퍼티와 다르게 열거형에서 사용이 가능하다는 특징을 발견할 수 있었습니다.

또한 저장하는 역할이 아닌 다른 저장 프로퍼티를 갖고 여러 작업을 수행 후 저장 프로퍼티에 넘겨준다라고 이해했습니다.

이제 예시를 볼까요?

struct Point {
    var x = 0.0, y = 0.0
}
struct Size {
    var width = 0.0, height = 0.0
}
struct Rect {
    var origin = Point()
    var size = Size()
    var center: Point {
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x: centerX, y: centerY)
        }
        set(newCenter) {
            origin.x = newCenter.x - (size.width / 2)
            origin.y = newCenter.y - (size.height / 2)
        }
    }
}
var square = Rect(origin: Point(x: 0.0, y: 0.0),
                  size: Size(width: 10.0, height: 10.0))
let initialSquareCenter = square.center
square.center = Point(x: 15.0, y: 15.0)
print("square.origin is now at (\(square.origin.x), \(square.origin.y))")
// "square.origin is now at (10.0, 10.0)" 출력

위의 예시는 좌표와 크기를 갖고 있는 사각형을 표현하는 구조체에 관한 코드 입니다.

Rect 구조체는 사각형의 중점을 표현하는 center 연산 프로퍼티를 갖고 있습니다.

getter 역할

get 은 다른 저장 프로퍼티의 값을 연산을 하고 결과값을 반환해주는 역할을 합니다.

get {
    let centerX = origin.x + (size.width / 2)
    let centerY = origin.y + (size.height / 2)
    return Point(x: centerX, y: centerY)
}

origin 인스턴스의 x 와 y 좌표, size 인스턴스의 가로, 세로 값을 통해 사각형의 중심 X,Y 좌표를 구하게 됩니다.

좌표를 구하는 연산을 하고 나온 결과값을 Point 구조체를 통해 값을 반환시켜줍니다.

setter 역할

set 은 파라미터로 받은 값을 다른 저장 프로퍼티에 저장을 할지 설정을 해줍니다.

set(newCenter) {
    origin.x = newCenter.x - (size.width / 2)
    origin.y = newCenter.y - (size.height / 2)
}

newCenter 라는 파라미터를 받게 되고 계산을 하게 되어 x, y 에 좌표값을 설정하게 됩니다.

정말 간단하죠?

set 은 더욱 간단하게 사용할 수 있는 방법도 존재합니다.


setter 간략한 표현

위의 코드를 보신 것처럼 파라미터를 newCenter 라고 이름을 지어주었습니다.

이름을 따로 설정하여 코드를 읽기 쉽게 해주는 것도 좋은 방법이지만 그럴 필요가 없는 경우 코드의 양만 많아진다는 단점이 있죠

set {
    origin.x = newValue.x - (size.width / 2)
    origin.y = newValue.y - (size.height / 2)
}

위의 코드 처럼 set 메소드 안에 파라미터의 이름을 지정하지 않아도 newValue 라는 이름으로 사용이 가능하다는 점입니다.


두개 다 선언을 해줘야 하나요?

모든 연산 프로퍼티가 상황에 따라 getset 를 필요하지는 않을 겁니다.

값을 읽기만 하는 get only 연산 프로퍼티 도 존재 합니다.

즉, 값을 읽고 반환하지만 다른 값을 지정할 수 없는 프로퍼티를 의미합니다.

struct Cuboid {
    var width = 0.0, height = 0.0, depth = 0.0
    var volume: Double {
        return width * height * depth
    }
}
let fourByFiveByTwo = Cuboid(width: 4.0, height: 5.0, depth: 2.0)
print("the volume of fourByFiveByTwo is \(fourByFiveByTwo.volume)")
// "the volume of fourByFiveByTwo is 40.0" 출력

Cuboid 라는 구조체 안에 저장 프로퍼티 ( width, height, depth ) 가 총 3개 있고 값을 return 하는 것을 보아 연산 프로퍼티 중 값을 읽고 반환만 시켜주는 읽기 전용 연산 프로퍼티를 의미합니다.

get 이라는 키워드가 없지만 get 구문을 없애 더욱 간편하게 사용이 가능합니다.

여기서 중요한 것은 읽기 전용 연산 프로퍼티는 let 이 아닌 var 로 만 선언이 가능하다는 것입니다.

읽기 전용 ( Read Only ) 이라는 뜻은 프로퍼티를 선언 시 한번 값이 정해지면 변하지 않기 때문에 let 으로 선언하는 것이 맞습니다.

하지만 결국 연산 프로퍼티 내에 속하기 때문에 읽기 전용 이라도 값이 변할 수 있어 var 로 선언을 해주어야 합니다.

그렇다면 set 만 존재하는 연산 프로퍼티도 존재할까요?

width 저장 프로퍼티를 새로운 값으로 설정하는 newWidth 연산 프로퍼티를 만들어 봤습니다.

아쉽게도 set 만 있는 연산 프로퍼티는 존재할 수 없고 get 과 같이 사용해야 한다고 합니다.


✅ getter, setter 정리

단어 뜻 그대로 get 은 무언가를 얻고, set 은 무언가를 설정하는 뜻을 갖고 있죠?

뜻 그대로 swift 에서도 get 은 저장 프로퍼티의 값을 통해 연산을 하고 값을 반환해주고 set 은 파라미터로 값을 전달받아 다른 저장 프로퍼티에 값을 저장해주는 역할입니다.

여기서 중요한 것은 연산 프로퍼티를 선언할 때는 타입을 정확히 적어주어야 한다는 것입니다!

var center: Point {
  get { .. }
  set { .. }
}

다음과 같이 어떤 타입이라는 것인지를 정확히 선언해주고 연산 프로퍼티는 항상 var 로 선언을 해주어야 한다는 점입니다.



🙋🏻 근데 왜 써야하지...?

그런데 가만히 생각을 해보니 왜 getset 이 필요한가? 라는 의문에 빠졌습니다.

값을 읽고 값을 수정하는 일은 다양한 방법으로 구현이 가능하고 저는 메서드를 통해 해당 작업을 수행 해왔었는데 굳이 써야하나 라는 생각이였습니다...

메서드와 프로퍼티 둘 중 어느것을 사용해야할까요....?

getset 을 왜 사용해야하는지 에 대한 글과 세번째 편인 Type Property ( 타입 프로퍼티 ) 에 대한 글로 찾아오겠습니다!

잘못된 부분이 있다면 언제든지 피드백 주시고 궁금한 부분이 있다면 댓글 남겨주세요!
같이 공부하면서 성장하는 시간이 되었으면 좋겠습니다!

profile
📱iOS Developer, 🍎 Apple Developer Academy @ POSTECH 1st, 💻 DO SOPT 33th iOS Part

0개의 댓글