Property [연산] - ehrldyd15/Swift_Skills GitHub Wiki
Property [연산]
연산프로퍼티
클래스, 구조체, 열거형에서 사용된다.
저장프로퍼티와는 달리 따로 저장공간을 갖지 않으며 다른 저장프로퍼티의 값을 읽어 연산하거나 프로퍼티로 전달받은 값을 다른프로퍼티에 저장한다.
따라서 항상 var로 선언되어야 한다.
var name: Type {
get { ✅ // getter(다른 저장 연산프로퍼티의 값을 얻거나 연산하여 리턴할 때 사용)
statements
return expr
}
set(name) { ✅ // setter(다른 저장프로퍼티에 값을 저장할 때 사용)
statements
}
}
연산프로퍼티는 위와 같은 생김새라고 보면 된다.
연산프로퍼티는 어떠한 값을 저장하는게 아니기 때문에 타입 추론을 통해 형식을 알 수 없다.
따라서 선언할때는 타입 어노테이션을 통해 자료형을 명시해야 한다.
그리고 선언된 자료형 뒤에는 {}를 붙여서 사용한다.
여기서는 어떤 타입의 값을 받아서 다른 저장프로퍼티에 저장할 것인지, 어떤 타입의 값을 리턴할 것인지 명시해주어야한다는 것이 핵심이다.
class Person {
var alias: String {
get { ❌
return alias ❌
}
set(name) { ❌
self.alias = name
}
}
}
위의 예제를 살펴보자
위처럼 작업하면 에러가 발생한다.
alias라는 연산프로퍼티는 값을 저장할 저장공간이 없는데 alias에 저장된 값을 읽으려고 하기 떄문이다.
class Person {
var name: String = "ABC" ✅
var alias: String {
get {
return name
}
set(name) {
self.name = name
}
}
}
name같은 읽거나 쓸 수 있는 저장프로퍼티가 먼저 존재해야 하고,
연산프로퍼티에선 이 다른 저장프로퍼티의 값을 읽거나 쓰는 작업을 해야한다.
class Person {
var name: String = "ABC"
var alias: String { ✅
get {
return self.name + "는 이름"
}
set(name) { ✅ // 참고로 파라메터 name의 타입을 따로 지정하지 않는 이유는 alias를 선언할떄 명시해주었기 떄문이다.
또한, 피라메터의 이름은 name 말고 임의대로 아무거나 사용할 수 있다.
self.name = name + "는 천재다."
}
}
}
let person: Person = .init()
print(person.alias) // ABC는 이름 ✅ get에 접근
person.alias = "나"
print(person.name) // 나는 천재다. ✅ set에 접근
위의 예제 처럼 사용하면 되겠다.
var name: String = "ABC"
var alias: String {
get {
return self.name + "는 이름"
}
set { ✅
self.name = newValue + "는 천재다." ✅
}
}
위의 예제는 set의 파라메터를 생략했다. 파라메터 대신 newValue를 사용하면 된다.
class Person {
var name: String = "ABC"
var alias: String {
get {
return self.name + "는 이름"
}
}
}
setter를 생략할 수 있다. 그냥 읽기만 가능하다고 하여 get-only라고 하는데
class Person {
var name: String = "ABC"
var alias: String {
return self.name + "는 이름"
}
}
이렇게 get 자체를 생략할 수 있다.
당연하겠지만 set이 없기 때문에
person.alias = "나" ❌ // error: Cannot assign to property: 'alias' is a get-only property
해당 오류가 발생한다.
var alias: String {
set { ❌ // set-only는 불가능하다. error: Variable with a setter must also have a getter
self.name = newValue + "는 천재다"
}
}
set-only는 불가능하다. 반드시 getter를 지녀야 한다는 에러가 발생한다.