구조체와 클래스를 이해하는데 제법 시간이 걸렸다.
구조체와 클래스의 가장 큰 차이점은
상속
이 가능하다는 점참조
타입, 구조체는 값
타입이라는 것이다.
상속은 이후에 배우는 내용이라 다음에 서술하고
참조타입과 값타입은 여기서 서술한다.
용어대로 클래스는 참조 타입인데 값을 참조
하여 보낸다는 뜻이고,
구조체는 값 타입으로 값을 복사
해서 보낸다는 뜻이다.
class PersonA {
var name: String = "jj"
}
struct PersonB {
var name: String = "jj"
}
var kim = PersonA()
let Lee = kim
var Park = PersonB()
let Choi = Park
print(kim.name,Lee.name) // prints "jj jj"
print(Park.name,Choi.name) // prints "jj jj"
kim.name = "kk"
Park.name = "kk"
print(kim.name,Lee.name) // prints "kk kk"
print(Park.name,Choi.name) // prints "kk jj"
PersonA,B 클래스와 구조체를 각각 만들었고
kim의 값을 Lee에, Park의 값을 Choi에 넣어주었다.
이때 클래스는 참조 타입이기 때문에 Lee
에는 kim
이 저장된 위치의 주소가 저장되게 되고
Choi
에는 Park
의 값이 복사되어 저장된다.
그래서 name의 값을 변경 했을 때 kim
과 같은 주소의 위치를 참조
하는
Lee
는 같이 값이 변경이 되었고
값이 복사만 되어버린 Choi
에는 값이 변경되지 않고
원래의 값이 그대로 저장되어 있다.
프로퍼티의 종류에는
이렇게 3종류로 나뉘는데
먼저 첫번째의 저장 프로퍼티는 기본적으로 사용하는 프로퍼티이다.
두번째의 지연 저장 프로퍼티는 var 앞에 lazy
를 붙여서 사용하는데 타입이 초기화 된 후에 값을 할당하는 프로퍼티이다.
struct Person {
var name: String = "jj"
lazy var nickname: String = "나는 " + self.name
}
var kim1 = Person()
print(kim1.nickname) // prints "나는 jj"
만약 lazy
를 붙이지 않으면 초기화 되기 전에 name
프로퍼티를 사용 했기 때문에 오류가 발생한다.
또 인스턴스를 생성할 때에도 구조체의 경우 let이 아닌 var로 선언을 해야한다.
nickname의 값이 변경되기 때문이다.
클래스의 경우에는 let으로 선언을 해주어도 무방하다.
그 다음 프로퍼티인 연산프로퍼티는 말 그대로 연산된 프로퍼티 이다
struct Person {
var name: String = "jj"
var nickname: String {
get {
return "나는 " + self.name
}
set(name) {
self.name = name
}
}
}
var kim1 = Person()
kim1.nickname = "제이"
print(kim1.name) // prints "제이"
print(kim1.nickname) // prints "나는 제이"
이렇게 값을 받아서 그 값을 연산해서 보내주고 처리할 수 있다.