struct가 무엇이고 어떻게 사용하는지 설명하시오.

이하연·2021년 8월 15일
0

[Swift] 스위프트

목록 보기
6/27

구조체와 클래스는 OOP를 위한 필수 요소로 프로그램의 코드를 추상화하기 위해 사용합니다.

또한 Swift에서는 다른 프로그래밍 언어와 달리 구조체와 클래스를 위한 별도의 인터페이스와 파일을 만들 필요가 없습니다.

Struct

  • 구조체란, 인스턴스의 값(프로퍼티)을 저장하거나, 기능(메소드)를 제공하고 이를 캡슐화할 수 있도록 스위프트가 제공하는 타입입니다.
  • 구조체는 struct 키워드로 정의합니다.
struct [구조체 이름] { 
    [프로퍼티와 메서드들]
}
  • 구조체 이름은 "새로운 타입을 생성해주는 것"과 마찬가지이므로, 기본 타입 이름처럼 대문자 카멜케이스를 사용하여 지어줍니다.
  • 프로퍼티와 메서드는 소문자 카멜케이스를 사용하여 이름을 지어줍니다.

Class

  • 클래스는 class 키워드로 정의합니다.
class [클래스 이름] { 
    [프로퍼티와 메서드들]
}

class [클래스 이름]: [부모클래스 이름] { 
    [프로퍼티와 메서드들]
}
  • 클래스 이름과 프로퍼티,메서드 - struct와 동일
  • 클래스는 부모 클래스가 없더라도 상속 없이 단독으로 정의가 가능합니다.
  • 만약, 상속받을 경우엔 클래스 이름 뒤에 콜론(:)을 써주고 부모클래스 이름을 명시

Class와 공통점

  • 프로그래머가 데이터를 용도에 맞게 묶어 표현하고자 할 때 용이합니다.
  • 프로퍼티와 메서드를 사용하여 구조화된 데이터와 기능을 가질 수 있습니다. 이는 하나의 새로운 사용자 정의 데이터 타입을 만들어 주는 것입니다.
  • Subscript 문법을 통해 구조체, 클래스가 가지는 값 (프로퍼티)에 접근하도록 서브스크립트를 정의 가능
  • 초기화될 때의 상태를 지정하기 위해 이니셜라이저를 정의
  • 새로운 기능 추가를 위해 extension을 통해 확장 가능
  • 특정 기능을 수행하기 위해 특정 프로토콜을 준수할 수 있다.

swift에서는 구조체와 클래스 모습과 문법이 거의 흡사하지만 둘은 분명한 차이점이 존재

Class와 차이점

  • Struct

    인스턴스 : 값 타입

    상속이 불가능

  • Class

    인스턴스 : 참조 타입

    단일 상속

    클래스 인스턴스에만 허용

    타입캐스팅

    Deinitializer

    참조 횟수 계산


Struct 사용 권장

애플은 다음 조건 중 하나 이상에 해당한다면 구조체를 사용하는 것을 권장

  1. 연관된 간단한 값의 집합을 캡슐화하는 것만이 목적일 때
  2. 캡슐화한 값을 참조하는 것보다 복사하는 것이 합당할때
  3. 구조체에 저장된 프로퍼티가 value 타입이며 참조하는 것보다 복사하는 것이 합당할 때
  4. 다른 타입으로부터 상속받거나 자신을 상속할 필요가 없을 때

Swift의 기본 데이터 타입은 모두 "구조체"

// String 타입의 기본 정의 코드
public struct String {
    /// An empty 'String'.
    public init()
}

스위프트의 기본 타입은 모두 구조체로 구현되어 있습니다. 이는 기본 데이터 타입은 모두 값 타입이라는 의미입니다. 따라서, 전달인자를 통해 데이터를 전달하면 모두 값 복사되어 전달될 뿐, 함수 내부에서 아무리 전달된 값을 변경하려고 시도해도 기존의 변수나 상수에는 전혀 영향 미치지 못합니다.



Struct 예시

// 프로퍼티 이름(name, age)으로 자동 생성된 이니셜라이저를 사용하여 구조체를 생성합니다. 
var yagomInfo: BasicInformation = BasicInformation(name: "yagom", age: 99)
yagomInfo.age = 100 // 변경 가능!
yagomInfo.name = "Bear" // 변경 가능!

// 프로퍼티 이름(name, age)으로 자동 생성된 이니셜라이저를 사용하여 구조체를 생성합니다.
let hanaInfo: BasicInformation = BasicInformation(name: "hana", age: 99)
hanaInfo.age = 100 // 변경 불가!
  • 구조체의 인스턴스를 생성후 초기화하기 → 멤버 와이즈 이니셜라이저 사용
  • 프로퍼티 값에 접근하고 싶을땐 → .(마침표) 사용
  • 값 변경
    • let - 변수를 let 선언시, 인스턴스 내부의 프로퍼티의 값은 변경 불가
    • var - 내부의 프로퍼티의 값이 변경 가능

Class 예시

class Person {
    var height: Float = 0.0
    var weight: Float = 0.0
}

var yagom: Person = Person()
yagom.height = 123.4
yagom.weight = 123.4

let hana: Person = Person()
hana.height = 123.4
hana.weight = 123.4

class Person {
    var height: Float = 0.0
    var weight: Float = 0.0
    deinit {
        print("Person 클래스의 인스턴스가 소멸됩니다.")
    }
}
var yagom: Person? = Person()
yagom = nil // Person 클래스의 인스턴스가 소멸됩니다.
  • 위 코드에선 Person 클래스는 프로퍼티의 기본값이 지정되어 있으므로 전달인자를 통해 초깃값을 전달하지 않아도 됩니다.

  • 마찬가지로, 프로퍼티 값에 접근하고 싶을때 → . 사용

  • 참조 타입

    • 구조체와 다르게 클래스 인스턴스는 참조 타입

      → 클래스의 인스턴스를 let으로 선언해도 내부 프로퍼티 값을 변경할 수 있다.

    • 클래스의 인스턴스는 더이상 참조할 필요가 없을때 메모리에서 해제됩니다.

      → 이 과정을 "소멸"

      → 소멸되기 직전 "deinit"라는 메서드가 호출됨

       (deinit 메서드 : 디이니셜라이저 ( Deinitializer )라고 부릅니다.)

      → deinit 메서드는 클래스당 하나만 구현 가능

      → 또한, 매개변수와 반환 값을 가질 수 없습니다. ( 소괄호 없음 )

      → 프로그래머가 직접 deinit 메서드를 호출할 수 없다.

      • deinit 메서드 구현해야 할땐 언제일까?

        인스턴스 소멸 전에 데이터를 저장한다거나 다른 객체에 인스턴스 소멸을 알려야 할 때


참고할 사이트

Swift 구조체(Structures)

0개의 댓글