Search
Duplicate

(Swift) Structures vs Classes

간단소개
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
Swift
Scrap
태그
inheritence
reference type
value type
9 more properties
Swift를 공부하면서 struct를 쓰는 것을 보고 조금 의아했다. class가 있는데 굳이 struct를 사용해야하나? 처음 사용법을 배우면서도 너무나도 비슷한 활용법에 의문을 품어서 대체 왜 struct와 class를 나눠서 사용하는지 찾아보았다.
이 포스트는 Apple의 Swift Documents를 보고 작성하였습니다

Comparing Structures and Classes

Both can:

Define properties to store values
Define methods to provide functionality
Define subscripts to provide access to their values using subscript syntax
Define initializers to set up their initial state
Be extended to expand their functionality beyond a default implementation
Conform to protocols to provide standard functionality of a certain kind
각각의 기능들에 대한 추가적인 설명은 아래 페이지에서 볼 수 있다.

Classes can:

class가 struct보다 더 많은 기능을 담고있기 때문에, class가 어떤 것을 더 할 수 있는지 알아보자.
Inheritance enables one class to inherit the characteristics of another.
Type casting enables you to check and interpret the type of a class instance at runtime.
Deinitializers enable an instance of a class to free up any resources it has assigned.
Reference counting allows more than one reference to a class instance.
각각의 기능들에 대한 추가적인 설명은 아래 페이지에서 볼 수 있다.
Apple공식 문서에서 두 구조 중 하나를 고르는 기준을 간단하게 정의해 두었다.
The additional capabilities that classes support come at the cost of increased complexity. As a general guideline, prefer structures because they’re easier to reason about, and use classes when they’re appropriate or necessary.
일반적인 상황에서는(특별히 복잡한 기능이 필요없는) struct를 사용하는 것을 권장하고, 만약 필요하다면 class를 사용하라고 나와있다. 아무래도 class는 추가적인 기능이 많기 때문에 많은 코드들을 담는 프로젝트에서 무분별한 사용보다는 필요한 상황에 적절히 사용하는게 좋은 것 같다.

Definition Syntax

이제 각각 어떻게 선언하는지 살펴보자
// structures struct SomeStructure { // Do Something } // classes class SomeClasses: SomeParentsClasses { // Do Something }
Swift
복사
Whenever you define a new structure or class, you define a new Swift type. Give types UpperCamelCase names (such as SomeStructure and SomeClass here) to match the capitalization of standard Swift types (such as String, Int, and Bool). Give properties and methods lowerCamelCase names (such as frameRate and incrementCount) to differentiate them from type names.
이 때, type은 uppercamelcase로, 속성이나 메서드는 lowercamelcase로 적는 것을 규칙으로 한다. 또한 struct, class의 이름은 되도록이면 파일의 이름과 동일하게 만든다.
ex. Student.swift → class Student

Structure and Class Instances

선언한 구조들의 객체는 아래와 같이 생성할 수 있다.
let someStruct = SomeStructure() let someClass = SomeClasses()
Swift
복사

Structures and Enumerations Are Value Types

A value type is a type whose value is copied when it’s assigned to a variable or constant, or when it’s passed to a function.
C++을 공부하다보면 Call by Value, Call by Reference와 같은 것을 자주 볼 수 있다. 해당 개념을 익히고 있다면 아래 부분을 어렵지 않게 이해할 수 있을 것이다.
Swift의 structures는 Value Type이다. 간단하게 예시를 통해서 살펴보자. 우선 BoxSize라는 struct를 만들었다. BoxSize는 height와 width를 가지고 있다. Main에서 BoxSize의 instance를 생성해 hd라는 변수에 담아보자.
struct BoxSize { var height: Int = 1080 var width = 1920 // 타입을 생략하면 타입추론을 해준다 }
Swift
복사
// in Main var hd = BoxSize() print("height = \(hd.height)") print("width = \(hd.width)")
Swift
복사
이 때, hd는 BoxSize로 생성한 객체이기 때문에 height와 width를 고정적으로 가지고 태어난다.
이제 우리는 여기서 cinema라는 객체를 만들어서 hd를 복사해보자. 그리고 cinema의 width property를 2048로 수정해보자
// in Main ... var cinema = hd cinema.width = 2048
Swift
복사
결과를 보면 cinema의 width속성만 바뀐 것을 알 수 있다. cinema는 hd의 모든 value를 그대로 복사해서 가져가 완전히 새로운 하나의 객체를 생성한 것을 알 수 있다.
그렇다면 Class는 어떨까?

Classes Are Reference Types

Unlike value types, reference types are not copied when they’re assigned to a variable or constant, or when they’re passed to a function. Rather than a copy, a reference to the same existing instance is used.
위의 설명에서 볼 수 있듯이 Classes는 함수에 전달되거나 변수에 할당될 때, 복사 대신 기존 객체에 대한 참조가 사용된다. struct에서 사용한 예시를 동일하게 class로 바꾸어 보자
class BoxSize { var height = 1080 var width = 1920 }
Swift
복사
// in Main var hd = BoxSize() var cinema = hd cinema.width = 2048 print("hd height = \(hd.height)") print("hd width = \(hd.width)") print("cinema height = \(cinema.height)") print("cinema width = \(cinema.width)")
Swift
복사
hd를 복사해서 cinema에 넣고 cinema의 width값을 바꿨을 뿐인데 hd와 cinema의 값이 모두 바뀐 것을 알 수 있다. class는 위에서 말했듯이 값을 복사해 넣는게 아니라 객체에 대한 참조를 사용하기 때문이다. 아래의 그림이 이해를 도와줄 것이다.

Identity Operators

클래스는 reference type이기 때문에 하나의 객체를 참조하는 여러개의 변수가 존재할 수 있다. 이 때, 각 변수들이 동일한 객체를 참조하는지 확인하는 도구가 있으면 유용할 것이다! 아래 연산자를 보자
=== // Identical to !== // Not Identical to
Swift
복사
Identical은 Equal과 다르다. Identical은 두 변수가 동일한 객체를 가리키는 것을 나타낸다. Equal에 대한 정의는 개발자의 역할이다.