9-1. 구조체와 클래스 비교, 구조체 개념(struct)

구조체와 클래스는 프로그램 코드의 구성요소가 되는 범용 구조이다. 상수, 변수, 그리고 함수를 정의하는 것과 같은 구문을 사용해서 구조체와 클래스에 프로퍼티와 메서드를 기능적으로 추가할 수 있다. 스위프트에서 클래스는 객체보다 좀 더 일반적인 인스턴스라는 용어를 사용한다.

구조체와 클래스의 비교

  1. 스위프트에서 구조체와 클래스는 공통점이 많다.
  • 값을 저장하는 프로퍼티 정의(Property)
  • 기능 제공을 위한 메서드 정의(Method, function)
  • 서브 스크립트 구문을 사용해 값에 접근을 제공하는 정의(Subscript)
  • 초기화 상태를 설정하기 위한 초기화 정의(Initialize)
  • 기본 구현을 넘어 기능적 확장을 위한 확장(Extension)
  • 특정 종류의 표준기능을 제공하는 프로토콜 준수(Protocol)
  1. 클래스는 구조체에 없는 추가적 기능이 있다.
  • 상속을 사용하면 하나의 클래스가 다른 클래스의 특성을 상속 가능하다.
  • 타입 캐스팅을 사용하면 런타임에 클래스 인스턴스의 타입을 확인하고 해석 가능하다.
  • 초기화 해제를(Deinit)을 사용하면 클래스의 인스턴스가 할당된 리소스를 해제할 수 있다.
  • 참조 카운팅은 하나 이상의 클래스 인스턴스 참조를 허락한다.

결과적으로 클래스는 복잡한 추가기능을 지원한다. 일반적 지침으로 추론하기 쉬운 구조체를 선호하며, 적절하거나 필요 시 클래스를 사용한다. 실질적으로 대부분 사용자 정의 데이터 타입은 구조체와 열거형이다.

  1. 클래스와 구조체는 유사한 정의구문을 가진다.
struct SomeStructure {
//구조체 정의
}

class someClass {
//클래스 정의
}

구조체와 클래스 인스턴스

  1. 다음의 예시에서 Resolution 구조체 정의와 VideoMode클래스 정의는 오직 각각의 모양만 설명한다. 자체적인 해상도 또는 비디오 모드에 대해 설명하지 않는다. 이러한 자체 설명을 위해서는 인스턴스 생성이 필요하다.
struct Resolution {
	var width = 0
    var height = 0
}

class VideoMode {
	var resolution = Resolution()
    var interlaced = false
    var frameRate = 0.0
    var name : String?
}
//다음 구조체와 클래스는 각각 프로퍼티를 가진다.
//저장된 프로퍼티는 구조체와 클래스 내 묶여 저장되는 상수 또는 변수이다.
  1. 구조체와 클래스는 모두 새로운 인스턴스를 위해 초기화 구문을 사용한다. 초기화 구문은 아래처럼 각 이름 뒤 ()소괄호를 붙여 사용하는 것이다. 여기에서 생성된 인스턴스의 프로퍼티에 접근이 가능하며 인스턴스 뒤에 점(.)을 붙이고 변수나 상수명을 명시하여 접근이 가능하다.
let someResolution = Resolution()
let someVideoMode = VideoMode()

//다음과 같이 각 인스턴스를 생성한다. 이게 무슨의미냐면 결과적으로는 각 구조체와 클래스에 틀에
//해당하는 데이터를 저장하고 핸들링하는 일종의 틀을 선언하는 것이다.
//클래스는 주형틀과도 같다. 내가 동을 넣으면 동전, 철을 넣으면 칼이 나온다.

print("\(someResolution.width)")
//다음과 같은 경우 0을 출력한다.
//someResolution에 프로퍼티 width를 참조하고 그 기본값 0를 반환하다.

someVideoMode.resolution.width = 1280
print(someVideoMode.resolution.width)
//1280을 출력하게 된다.

구조체 타입에 대한 멤버별 초기화 구문

  1. 모든 구조체는 새로운 구조체 인스턴스의 멤버 프로퍼티를 초기화 할 때 사용할 수 있는 자동적으로 생성된 멤버별 초기화 구문을 가지고 있다.
let vga = Resolution(width : 640, height : 480)
//다음과 같이 새로운 구조체 값을 가지는 상수를 선언할 수 있다.
  1. 구조체와 반대로 클래스 인스턴스는 멤버별 초기화를 받지 않는다.
  2. 구조체와 열거형은 값 타입이다.(value type) 값 타입은 변수 또는 상수에 할당될 때나 함수에 전달될 때 복사되는 타입이다. 실제로 스위프트에서는 Int, Double, Float, Bool, String, Array, Character, Dictionary등이 모두 값 타입이고 구조체로 구현되어 있다. 구조체가 값 타입이라는 말은 생성한 구조체나 열거형의 모든 프로퍼티가 전달될 때 다 복사된다는 의미이다.
  let hd = Resolution(width : 1920, height : 1080)
  var cinema = hd
  cinema.width = 2048
  print(cinema.width)
  //2048을 출력한다. 마치 변수에 상수를 담고 변수값을 변환해 준 것같이 자연스럽게 계산된다.
  print(hd.width)
  //1920을 그대로 가지고 있다. 
  
  //이것은 cinema에 hd의 현재값이 주어질 때 새로운 인스턴스에 복사가 된다. 
  //그래서 이 둘은 완전하게 다르고 분리된 2개의 인스턴스이다. 따라서 서로 영향이 없는 것이다.
  1. 열거형에서도 같은 동작이 그대로 이루어지게 된다.
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개의 인스턴스를 생성하게 된다.
  

좋은 웹페이지 즐겨찾기