Swift

❓ 연산 프로퍼티

_yunie 2024. 6. 5. 13:30

안녕하세요! 한 주의 중간인 딱 노곤해지는 수요일이네요!

그래도 내일이면 휴일이라니 여러모로 여유있게 보낼 수 있을 것 같아 기분이 좋습니다☺️

 

이제 본론으로 들어가자면 저번 글에서는 저장 프로퍼티에 대해 알아봤습니다

그때, 프로퍼티는 저장 / 연산 / 타입 프로퍼티 이렇게 총 세 가지로 나뉜다고 말씀드렸는데요!

오늘은 연산 프로퍼티에 대해 공부해볼 생각입니다!

 

 

❓ 연산 프로퍼티

저장 프로퍼티는 이전 글에서 말했다시피 우리가 아는 일반적인 프로퍼티 형식을 이야기합니다

그렇다면 연산 프로퍼티는 뭘까요? 이름처럼 무언가를 연산해 주는 프로퍼티인가..?라고 우리는 자연스레 추측해 볼 수 있습니다

그리고 네, 맞습니다!

연산 프로퍼티는 다른 저장 프로퍼티의 값을 가져와 연산을 수행하거나, 프로퍼티로 전달받은 값을 다른 프로퍼티에 저장해 주는 역할을 합니다

그렇기 때문에 값이 휙휙 변할 수 있어서 항상 var로 선언해주어야 합니다

또한, 연산 프로퍼티는 저장 프로퍼티와 다르게 열거형에서도 사용할 수 있고 저장 공간을 가지지 않습니다

아무래도 직접 값을 가지는 것이 아니라 다른 저장 프로퍼티를 이용하는 형태의 프로퍼티이기 때문인거겠죠?

 

이제 연산 프로퍼티의 기본 구조를 살펴보겠습니다

import UIKit

struct Human {
    let name: String // 저장 프로퍼티
    var hobby: String // 저장 프로퍼티 
    
    var introduce: String { // 연산 프로퍼티 
        get { // getter : 다른 저장 프로퍼티를 가지고 연산한 후 return 
            return "제 이름은 \\(name)이고 취미는 \\(hobby)입니다"
        }
        set { // setter : 다른 저장 프로퍼티에 새로운 값을 저장
            hobby = newValue
        }
    }
}

var yunie = Human(name: "yunie", hobby: "영화보기")
print(yunie.introduce) // 제 이름은 yunie이고 취미는 영화보기입니다

 

어때요? 코드로 보니까 어떤 형태로 사용하는지 좀 감이 오시나요? 아니면 너무 어려워 보이시나요?

단순히 연산해 주거나 저장하는 걸 도와주는 프로퍼티인 줄 알았더니, get이며 set이며..🤯 잘 모르셔도 괜찮습니다!

이제부터 알아가면 되니까요🔥

 

그럼 차근차근히 뜯어볼게요

var introduce: String 

 

여기까지는 우리가 아는 저장 프로퍼티와 형태가 동일합니다

하지만 저장 프로퍼티는 해당 타입의 데이터를 가진다고 명시한 것이라면 연산 프로퍼티는 해당 타입의 데이터를 반환하거나 해당 타입의 데이터를 값을 받아올 것이라고 명시해 주는 입니다

 

var introduce: String {
	get { // getter : 다른 저장 프로퍼티를 가지고 연산한 후 return 
	  return "제 이름은 \\(name)이고 취미는 \\(hobby)입니다"
	}
}

 

그리고 자료형을 명시해 준 이후에 { }를 통해 연산에 관한 코드(get, set 구문)를 작성해 줍니다

현재 코드에서 introduce는 같은 구조체인 Human 내의 name과 hobby를 이용해 새로운 문자열을 반환해주고 있습니다

이처럼 getter는 연산에 사용하고자 하는 저장 프로퍼티를 가져와(get) 연산을 수행하고 return 해주는 친구라고 생각해 주시면 됩니다!

 

그럼 범위를 넓혀 setter까지 살펴보겠습니다

var introduce: String { // 연산 프로퍼티 
        get { // getter : 다른 저장 프로퍼티를 가지고 연산한 후 return 
            return "제 이름은 \\(name)이고 취미는 \\(hobby)입니다"
        }
        set { // setter : 다른 저장 프로퍼티에 새로운 값을 저장
            hobby = newValue
        }
    }

 

setter은 이름에서도 알 수 있듯이 받아온 데이터를 어떠한 저장 프로퍼티에 새로이 설정해 주는 역할을 합니다

저는 영화 보기 이외에도 스포츠 경기 직관, 달리기 등 다양한 취미를 가지고 있는데요

소개할 때마다 취미를 달리하여 소개하고 싶어 hobby에 새로운 값을 넣어주는 형태로 setter를 구성하고 있습니다

 

우선 영화 보기라는 취미로 저를 소개하기 위해 아래 코드처럼 인스턴스를 생성해 주었습니다

그리고 print문을 통해 introduce 프로퍼티에 접근하면 제가 입력한 name과 hobby를 이용한 문장이 제대로 반환되는 것을 확인할 수 있습니다

저장 프로퍼티를 사용하는 방법과 딱히 다르지 않습니다

var yunie = Human(name: "yunie", hobby: "영화보기")
print(yunie.introduce) // 제 이름은 yunie이고 취미는 영화보기입니다

 

다음 소개 시에는 스포츠 경기 직관하는 게 취미라고 소개해볼까요?

이때, 우리는 setter를 이용하게 됩니다

yunie.introduce = "스포츠 경기 직관"
print(yunie.introduce) // 제 이름은 yunie이고 취미는 스포츠 경기 직관입니다

 

자, 바뀐 소개문장이 보이시나요?

setter를 이용해 ‘스포츠 경기 직관’이 hobby에 새로이 저장되고 바뀐 데이터를 가지고 새로운 문장을 만들어낸 getter가 실행된 결과입니다!

 

이제 연산 프로퍼티가 어떤 녀석인지 감이 잡히셨겠죠?😉

 

 

🧐 newValue의 타입은 왜 명시하지 않나요?

 

어떤 호기심이 많으신 분들은 ‘연산 프로퍼티가 어떤 방식으로 동작하는지 이해했는데, 저 newValue라는 친구는 어떻게 String인걸 알고 저렇게 대입할 수 있지?’라는 호기심이 생길 수 있습니다

 

왜 그런 걸까요? 정답은 간단합니다

이미 연산 프로퍼티를 선언할 때 String이라고 타입을 명시해 주었기 때문입니다

결국, 들어오고 나가는 데이터가 String이라고 이미 모두가 알고 있는 상황인거에요!

 

그리고 newValue는 애플이 지정해 둔 파라미터명으로 NewValue, newvalue와 같은 경우는 불가능합니다!

다만 원하는 다른 이름으로 바꿔서 사용할 수는 있습니다

set(hb) {
	hobby = hb
}

이런 식으로요!

 

 

❓get-only

연산 프로퍼티를 쓸 때 setter가 필요 없어 getter로만 구성해 준다면 그것을 get-only라고 칭합니다

그리고 이런 경우에 get은 생략할 수도 있습니다

var introduce: String { // 연산 프로퍼티 
 	// getter만 있는 형태 -> get-only
   	 return "제 이름은 \\(name)입니다!"
  }

 

 

🧐 그럼 set-only도 있나요?

안타깝지만 대답은 NO! 입니다

setter는 getter이 구현된 상태에서만 넣어줄 수 있기 때문에 단독으로 사용해 주게 된다면 에러메시지를 마주하실 겁니다

 

 

❗️ 연산 프로퍼티를 사용할 때 주의할 점

그리고 연산 프로퍼티는 다른 저장 프로퍼티의 값을 연산해 주는 역할만을 맡고 있기 때문에 만약 자기 자신을 연산하고자 한다면 오류 메시지가 뜨는 것을 확인할 수 있습니다

이는 getter가 무한정 불러와지는 결과를 불러오기 때문에 ⚠️ 연산 프로퍼티를 사용할 때에는 꼭 자신을 제외한 다른 저장 프로퍼티를 사용해야 함 기억해 주시면 좋을 것 같아요☺️

 

 

📚 참고

Swift) 프로퍼티 정복하기 (2/4) - 연산 프로퍼티(Computed Property)

[Swift] 프로퍼티 개념 정리 (2); 연산 프로퍼티

[Swift 기초] - 프로퍼티(Properties) 종류

'Swift' 카테고리의 다른 글

❓ Delegate와 DataSource의 차이  (1) 2024.06.10
❓ 타입 프로퍼티  (2) 2024.06.07
❓ 저장 프로퍼티  (0) 2024.05.31
❓final  (0) 2024.05.27
❓lazy  (0) 2024.05.20