구조체는 값을 저장하고, 그와 관련된 함수를 정의할 수 있는 데이터 타입으로 클래스와 비슷하다.
[구조체와 클래스의 차이]
/ | 구조체 | 클래스 |
타입 | Value Type 그 인스턴스의 값이 복사되어 완전한 독립적인 형태를 가지게 됨 | Reference Type |
상속 | 상속을 지원하지 않음 | 클래스가 다른 클래스로부터 기능을 상속받고, 상속된 기능을 확장하거나 재정의 할 수 있음 |
메모리 관리 | 스택 메모리에 저장 됨 | 힙 메모리에 저장되며, *ARC를 사용해 메모리를 관리함. 그로인해 더 많은 메모리와 리소스를 사용하게 된다 |
불변성 | let으로 선언된 인스턴스의 모든 프로퍼티는 변경할 수 없음 | let으로 전언되었더라도 그 인스턴스의 프로퍼티는 수정가능하다 |
Mutating | 구조체의 메서드가 인스턴스 프로퍼티를 변경하려면 mutating키워드를 사용해야함 | mutating 키워드 사용없이 자유롭게 변경 가능함 |
동일성 비교 | 실제 값을 비교함, 같은 값을 가지고 있으면 동일한것으로 간주 | 참조 위치를 비교함, 두 객체가 같은 메모리 위치를 참조하는지를 확인하므로 값이 같더라도 참조가 다르면 다른 객체로 간주 됨 |
용도 | 객체를 모델링할때에 사용되며 주로 작은 데이터를 다룸 | 데이터가 공유되거나 객체 간 상속이 필요한 경우 계정 관리, 네트워크 연결 처리 등에 적합 |
*ARC(Automatic Reference Counting)는 객체의 참조 횟수를 자동으로 계산하여, 참조 횟수가 0이 되면 해당 객체를 메모리에서 해제하는 방식으로 메모리를 관리함
[구조체]
할당 시 복사되므로 원본과 복사본은 서로 독립적인 상태를 가지며 서로에게 영향을 주지 않는다.
struct 키워드를 사용하여 정의되며, 내부에는 프로퍼티(변수나 상수)와 메서드(함수)를 가질 수 있다
기본형태
struct 구조체명 {
프로퍼티나 메서드등을 작성
}
사용
//구조체 정의 struct Sample { var mutableProperty : Int = 100 let immutableProperty : Int = 100 static var typeProperty : Int = 100 func instanceMethod(){ print("instance method") } static func typeMethod(){ typeProperty += 1 print("type method") } }
인스턴스를 var로 생성해줄 경우 가변 인스턴스로 내부 프로퍼티를 변경할 수 있으나, 프로퍼티 선언자체에서 let 키워드로 선언되었다면 그 프로퍼티는 변경할 수 없다
//가변 인스턴스 var newSample :Sample = Sample() newSample.mutableProperty = 50 newSample.immutableProperty = 50 //에러
인스턴스를 let으로 생성할 경우 내부의 값을 가변 프로퍼티로 선언했다 하여도 변경 할 수 없다.
//불변 인스턴스 let newSample :Sample = Sample() newSample.mutableProperty = 50 //에러 newSample.immutableProperty = 50 //에러
static
static은 인스턴스완 독립적으로 구조체 자체에 속하는 프로퍼티와 메서드를 정의하는 데 사용됨
static은 인스턴스를 생성하지 않고 타입 자체에서 접근할 수 있다
인스턴스마다 고유한 값을 가지는 다른 프로퍼티나 메서드와 다르게 구조체 전체에서 하나의 값만을 유지한다
newSample.typeProperty //에러 반환 Sample.typeMethod() print(Sample.typeProperty) //출력 101
예제 코드
struct Menu { var name : String = "아메리카노" var price : Int = 4000 static func menuIntroduction () -> Void { print("메뉴는 아래와 같습니다.") } func menuIntroduction () -> Void{ print("\(name)의 가격은 \(price)입니다.") } } Menu.menuIntroduction() var coffee : Menu = Menu() coffee.name = "바닐라크림 콜드블루" coffee.price = 6500 coffee.menuIntroduction() // 출력 // 메뉴는 아래와 같습니다. // 바닐라크림 콜드블루의 가격은 6500입니다.
[클래스]
참조 타입으로, 객체를 여러 변수나 함수에서 참조할 때 같은 객체를 공유하므로 서로에게 영향을 미친다
class 키워드를 통해 정의한며, 내부에는 프로퍼티(변수나 상수)와 메서드(함수)를 가질 수 있다
기본형태
class 클래스명 { //구현부 }
사용
//클래스를 정의 class Person { var name: String var age: Int init(name: String, age: Int) { self.name = name self.age = age } }
//할당하여 사용 let person1: Person = Person(name: "영희", age: 19) print(person1.name) //영희 출력 print(person1.age) // 19 출력
상속
//위에 정의한 Person의 타입을 상속받아 //해당 타입을 가지면서 자기만의 타입을 더 추가할 수 있다 class Adult : Person { var job : String var maritalStatus : Bool init(job: String, maritalStatus: Bool, name:String,age:Int) { self.job = job self.maritalStatus = maritalStatus super.init(name: name, age: age) } } let adult1 :Adult = Adult(job: "주부", maritalStatus: true, name: "김영희", age: 36) print(adult1.job) //주부 출력 print(adult1.name) //김영희 출력
참조 타입으로 참조 위치를 공유하기 때문에 할당한 후 값을 바꾸면 따라 바뀜
class Person { var name: String var age: Int init(name: String, age: Int) { self.name = name self.age = age } } let person1 : Person = Person(name: "박철수", age: 23) let person2 = person1 person1.age = 36 print(person2.age)