Search
Duplicate

구조체와 클래스의 차이

생성일
2023/09/12 05:38
태그
Grammar

구조체와 클래스의 차이

 같은 점

값을 저장하기 위해 프로퍼티를 정의할 수 있다.
기능 실행을 위해 메서드를 정의할 수 있다.
서브스크립트 문법을 통해 구조체 또는 클래스가 갖는 값(프로퍼티)에 접근하도록 서브스크립트를 정의할 수 있다.
초기화될 때의 상태를 지정하기 위해, 이니셜라이저를 정의할 수 있다.
초기구현과 더불어 새로운 기능 추가를 위해 익스텐션을 통해 확장할 수 있다.
특정 기능을 실행하기 위해 특정 프로토콜을 준수할 수 있다.

 다른 점

구조체는 상속할 수 없다.
타입캐스팅은 클래스의 인스턴스에만 허용된다.
디이니셜라이저는 클래스의 인스턴스에만 활용할 수 있다.
참조 횟수 계산(Reference Counting)은 클래스의 인스턴스에만 적용된다.
구조체와 클래스는 겉보기에 정의하는 방법, 인스턴스화하는 방법, 프로퍼티와 메서드를 갖는다는 점을 비롯해 많은 부분에서 비슷해보인다.
그러나 이 두 타입을 구분 짓는 가장 큰 차이점은 값 타입 참조 타입 이라는 것이다.
그래서 참조 횟수 계산은 클래스의 인스턴스에만 해당된다.

 Struct는 값 타입, Class는 참조 타입

값 타입과 참조 타입의 가장 큰 차이는 ‘무엇이 전달되느냐’ 이다.
예를들어, 함수의 파라미터로 값 타입의 값을 넘긴다면 전달될 값이 복사되어 전달 이 된다.
그러나 참조 타입이 파라미터로 전달될 때는 값을 복사하지 않고 참조(주소)가 전달 된다.
struct BasicInfo { let name: String var age: Int } var hjInfo: BasicInfo = BasicInfo(name: "hj", age: 99) hjInfo.age = 100 // hjInfo의 값을 복사하여 할당한다. var friendInfo: BasicInfo = hjInfo print("hj's age: \(hjInfo.age)") // 100 print("friend's age: \(friendInfo.age)") // 100
Swift
복사
class Person { var height: Float = 0.0 var weight: Float = 0.0 } var hj: Person = Person() var friend: Person = Person() print("hj's height: \(hj.height)") // 0.0 print("friend's height: \(friend.height)") // 0.0 friend.height = 185.5 print("hj's height: \(hj.height)") // 185.5 - friend는 hj를 참조하기 때문에 값이 변동 print("friend's height: \(friend.height)") // 185.5 - hj가 참조하는 곳과 friend가 참조하는 곳이 같음을 알 수 있다
Swift
복사
func changeBasicInfo(_ info: BasicInfo) { var dopiedInfo: BasicInfo = info copiedInfo.age = 1 } func changePersonInfo(_ info: Person) { info.height = 155.3 } // changeBasicInfo(_:)로 전달되는 전달인자는 갑이 복사되어 전달되기 떄문에 // hjInfo의 값만 전달된다. changeBasicInfo(hjInfo) print("hj's age: \(hjInfo.age)") // 100 // changePersonInfo(_:)의 전달인자로 hj의 참조가 전달되었기 때문에 // hj가 참조하는 값들에 변화가 생긴다. changePersonInfo(hj) print("hj's height: \(hj.height)") // 155.3
Swift
복사
값 타입의 데이터를 함수의 파라미터로 전달하면 메모리에 파라미터를 위한 인스턴스가 새로 생성된다.
생성된 새 인스턴스에는 전달하려는 값이 복사되어 들어간다.
반면, 참조 타입의 데이터는 파라미터로 전달할 때, 기존 인스턴스의 참조를 전달하므로 새로운 인스턴스가 아닌 기존의 인스턴스 참조를 전달한다.
함수의 파라미터 뿐만 아니라 새로운 변수에 할당될 때 또한 마찬가지이다.
클래스의 인스턴스끼리 참조가 같은지 확인할 때는 식별 연산자(Identity Operators) 를 사용한다.
var hj: Person = Person() let friend: Person = hj // hj의 참조를 할당한다 let anotherFriend: Person = Person() // 새로운 인스턴스를 생성한다 print(hj === friend) // true print(hj === anotherFriend) // false print(friend !== anotherFriend) // true
Swift
복사

❗️스위프트의 기본 데이터 타입은 모두 구조체로 이루어져 있다.

String, Bool, Int, Array, Dictionary, Set 등등스위프트의 기본 데이터 타입은 모두 구조체로 구현되어져 있다.
→ 이는 기본 데이터 타입은 모두 값 타입 이라는 뜻이다.
 파라미터를 통해 데이터를 전달하면 모두 값이 복사되어 전달될 뿐, 함수 내부에서 아무리 전달된 값을 변경해도 기존의 변수나 상수에는 전혀 영향을 미치지 못한다.

 구조체와 클래스 선택해서 사용하기

애플의 가이드라인에서 다음 조건 중 하나 이상에 해당한다면 구조체를 사용하는 것을 권장한다.
연관된 간단한 값의 집합을 캡슐화하는 것만이 목적일 때
캡슐화한 값을 참조하는 것보다 복사하는 것이 합당할 때
구조체에 저장된 프로퍼티가 값 타입이며 참조하는 것보다 복사하는 것이 합당할 때
다른 타입으로부터 상속받거나 자신을 상속할 필요가 없을 때