Swift의 모든 타입은 struct, class, enum으로 이뤄져 있다.
/*
struct 구조체 이름{
프로퍼티(멤버변수), 메소드(멤버함수)
}
*/
struct User {
var nickname: String
var age: Int
func information(){
print("\(nickname) \(age)")
}
}
프로퍼티 이름으로 자동 생성된 이니셜라이저를 사용하여 구조체를 생성한다.
var user1 = User(nickname: "HyunJae" , age: 27) //인스턴스 생성
user1.nickname = "JaeHyun" //값 변경가능
user1.information() // JaeHyun 27
let user2 = User(nickname: "JuYeon", age: 26)
user2.nickname = "J" //error: 변경불가
스위프트의 기본 데이터 타입은 모두 구조체!
ex. String, Int, Bool, Array, Set, ...
따라서 함수 내부에서 아무리 전달된 값을 변경해도 기존의 변수, 상수에는 전혀 영향을 미치지 못한다.
스위프트의 클래스는 부모클래스가 없더라도 상속 없이 단독으로 정의가 가능하다.
/*
class 구조체 이름{
프로퍼티(멤버변수), 메소드(멤버함수)
}
*/
class Dog {
var name: String = ""
var age: Int = 0 //name,age -> 저장 프로퍼티
init() {
} //생성자** (기본적으로 생성되고, 꼭 필요함. 여기서는 프로퍼티의 기본값이 지정되어있으므로 따로 초깃값 전달할 필요 없음)
func introduce() {
print("name \(name) age \(age)")
}
}
다른 언어에서 클래스의 객체라고 부르지만, 스위프트에서는 인스턴스라고 부른다.
var dog1 = Dog()
dog1.name = "Darong"
dog1.age = 10
let dog2 = Dog()
dog2.name = "Bori"
dog2.age = 13
클래스의 인스턴스는 참조 타입이므로, let으로 인스턴스를 선언해도 내부 프로퍼티 값을 변경할 수 있다.
참조타입이므로, 더는 참조가 필요없을 때 메모리에서 해제된다. [소멸]
class User{
var nickname: String
var age: Int
init(nickname: String, age: Int){
self.nickname = nickname
self.age = age
}
init(age: Int) {
self.nickname = "HyunJae"
self.age = age
}
deinit {
print("deinit user") //인스턴스가 메모리에서 해제되기 직전에 처리할 코드
}
}
var user = User(nickname: "JuYeon", age: 26)
var user2 = User(age: 25)
var user3: User? = User(age: 23)
user3 = nil //인스턴스가 더이상 필요하지 않다고 판단하여 메모리 해제. deinit 호출
deinit: 디이니셜라이저
구조체와 클래스 비교
공통점
- 프로퍼티, 메소드를 가진다.
- 이니셜라이저를 정의하여 초기화될 때의 상태를 지정할 수 있다.
- 서브스크립트 문법을 통해, 구조체 또는 클래스가 갖는 값(프로퍼티)에 접근하도록 서브스크립트를 정의할 수 있다.
차이점
- 구조체는 상속할 수 없다.
- 구조체의 인스턴스는 값 타입, 클래스의 인스턴스는 참조타입이다.
-> 타입캐스팅, 디이니셜라이저, 참조횟수계산은 클래스의 인스턴스에만 적용됨
값 타입: 전달될 값이 복사되어 전달됨
참조타입: 값을 복사하지 않고 참조(주소)가 전달됨
//선언
enum CompassPoint: String{
case north = "북"
case south = "남"
case east = "동"
case west = "서"
}
//열거형 변수 생성
var direction = CompassPoint.east
direction = .east //열거형 이름 생략 가능
//값 변경-> 같은 타입인 CompassPoint 내부 항목으로만 direction의 값 변경 가능
direction = .north
//원시값 rawValue 지정과 사용
switch direction {
case .north:
print(direction.rawValue) //북
case .south:
print(direction.rawValue) //남
}
let direction2 = CompassPoint(rawValue: "남")
//열거형의 연관값
enum PhoneError {
case unknown
case batteryLow(String)
}
let error = PhoneError.batteryLow("배터리가 곧 방전됩니다.")
참고: <스위프트 프로그래밍 3판> 야곰 저, 한빛미디어