구조체와 클래스는 프로그램 코드의 구성요소가 되는 범용 구조이다. 상수, 변수, 그리고 함수를 정의하는 것과 같은 구문을 사용해서 구조체와 클래스에 프로퍼티와 메서드를 기능적으로 추가할 수 있다. 스위프트에서 클래스는 객체보다 좀 더 일반적인 인스턴스라는 용어를 사용한다.
결과적으로 클래스는 복잡한 추가기능을 지원한다. 일반적 지침으로 추론하기 쉬운 구조체를 선호하며, 적절하거나 필요 시 클래스를 사용한다. 실질적으로 대부분 사용자 정의 데이터 타입은 구조체와 열거형이다.
struct SomeStructure {
//구조체 정의
}
class someClass {
//클래스 정의
}
struct Resolution {
var width = 0
var height = 0
}
class VideoMode {
var resolution = Resolution()
var interlaced = false
var frameRate = 0.0
var name : String?
}
//다음 구조체와 클래스는 각각 프로퍼티를 가진다.
//저장된 프로퍼티는 구조체와 클래스 내 묶여 저장되는 상수 또는 변수이다.
let someResolution = Resolution()
let someVideoMode = VideoMode()
//다음과 같이 각 인스턴스를 생성한다. 이게 무슨의미냐면 결과적으로는 각 구조체와 클래스에 틀에
//해당하는 데이터를 저장하고 핸들링하는 일종의 틀을 선언하는 것이다.
//클래스는 주형틀과도 같다. 내가 동을 넣으면 동전, 철을 넣으면 칼이 나온다.
print("\(someResolution.width)")
//다음과 같은 경우 0을 출력한다.
//someResolution에 프로퍼티 width를 참조하고 그 기본값 0를 반환하다.
someVideoMode.resolution.width = 1280
print(someVideoMode.resolution.width)
//1280을 출력하게 된다.
let vga = Resolution(width : 640, height : 480)
//다음과 같이 새로운 구조체 값을 가지는 상수를 선언할 수 있다.
let hd = Resolution(width : 1920, height : 1080)
var cinema = hd
cinema.width = 2048
print(cinema.width)
//2048을 출력한다. 마치 변수에 상수를 담고 변수값을 변환해 준 것같이 자연스럽게 계산된다.
print(hd.width)
//1920을 그대로 가지고 있다.
//이것은 cinema에 hd의 현재값이 주어질 때 새로운 인스턴스에 복사가 된다.
//그래서 이 둘은 완전하게 다르고 분리된 2개의 인스턴스이다. 따라서 서로 영향이 없는 것이다.
enum CompassPoint {
case north, south, east, west
mutating func turnNorth() {
self = .north
}
}
var currentDirection = CompassPoint.west
let rememberedDirection = currentDirection
currentDirection.turnNorth()
print(currentDirection)
//north를 출력하게 된다.
print(rememberedDirection)
//west를 출력하게 된다.
//열거형도 마찬가지로 값이 복사되고 서로 완전히 다른 2개의 인스턴스를 생성하게 된다.