[Swift 문법] struct, class, enum

pom·2023년 4월 8일

Swift의 모든 타입은 struct, class, enum으로 이뤄져 있다.

🥯 Struct : 구조체

🧁 정의

/*
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 구조체 이름{
	프로퍼티(멤버변수), 메소드(멤버함수)
}
*/

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: 디이니셜라이저

  • 클래스 당 하나만 구현 가능
  • 매개변수와 반환 값을 가질 수 없음
  • 인스턴스가 메모리에서 해제되기 직전에 처리할 코드를 넣어준다.
    ex. 인스턴스 소멸 전 데이터 저장해야할 때, 다른 객체에 인스턴스 소멸을 알려야 할 때

구조체와 클래스 비교

공통점

  • 프로퍼티, 메소드를 가진다.
  • 이니셜라이저를 정의하여 초기화될 때의 상태를 지정할 수 있다.
  • 서브스크립트 문법을 통해, 구조체 또는 클래스가 갖는 값(프로퍼티)에 접근하도록 서브스크립트를 정의할 수 있다.

차이점

  • 구조체는 상속할 수 없다.
  • 구조체의 인스턴스는 값 타입, 클래스의 인스턴스는 참조타입이다.
    -> 타입캐스팅, 디이니셜라이저, 참조횟수계산은 클래스의 인스턴스에만 적용됨

값 타입: 전달될 값이 복사되어 전달됨
참조타입: 값을 복사하지 않고 참조(주소)가 전달됨


🥯 Enum : 열거형

  • 연관된 항목들을 묶어서 표현할 수 있는 타입
  • 추가,수정 불가
  • C언어 등에서 모든 열거형의 데이터 타입은 같은 타입으로 취급하지만, 스위프트의 열거형은 각 열거형이 고유의 타입으로 인정된다.
  • 올바르지 않은 원시값을 통해 변수/상수를 생성하려한다면, nil을 반환
//선언
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판> 야곰 저, 한빛미디어

profile
Developer

0개의 댓글