[Swift] Struct 사용법

Updated:

Struct란

  • 여러 다른 타입의 데이터들을 담을 수 있는 데이터 타입이다.
  • 값 타입이며, 힙(heap)이 아닌 스택(stack) 에 데이터가 할당된다.

Struct 정의

struct Person {
    var name: String
    var age: Int
    
     func greet() {
        print("Hello, I'm \(name) and I'm \(age) years old.")
    }

struct 메서드 내에서 프로퍼티를 변경하고자 할때에는 mutating 키워드를 사용한다.

mutating func greet() {
     self.name = "이름"
}

참조타입이 아닌 값 타입을 사용해야 하는 경우

하나의 인스턴스를 공유해야 하는 경우가 아니라 각각의 인스턴스를 사용해야 하는 것이 합당하면 struct 를 사용한다. 아래의 예시는 참조타입인 class 였다면 하나의 인스턴스를 공유하지만, struct 이기에 값 복사가 이루어져 다른 인스턴스를 사용하게 된다.

// create an instance of Person
var person1 = Person(name: "Alice", age: 25)

// create another instance by copying person1
var person2 = person1

// modify person2's name
person2.name = "Bob"

// print person1's name
print(person1.name) // Alice

// print person2's name
print(person2.name) // Bob

Swift 에서 Struct를 사용해야만 하는 주요 이유

Swift 에서 structclass 가 가지는 거의 모든 기능을 제공하고 있다.

  • 생성자
  • 프로퍼티와 메서드
  • extension
  • Protocol 채택

하지만, class 가 가지는 OOP 로서의 중요한 ‘상속’ 기능을 지원하고 있지는 않다. 상속이 OOP 관점에서 중요한 이유는 부모 클래스로부터 물려받는 메서드와 프로퍼티들이 재사용 가능하며, 이들을 overriding 하여 다형성을 구현할 수 있기 때문이다.

struct로 구현하는 다형성과 POP(Protocol Oriented Programming)

Swift 언어가 공식적으로 지향하는 프로그래밍 패러다임이 있는데 이가 바로 ‘프로토콜 지향 프로그래밍(POP)’ 이다. POP 는 참조타입은 class 보다 값타입인 struct 를 지향하는 프로그래밍 패러다임이다. 참조 타입으로부터의 오류 최소화와 자요로움을 추구한다. POP의 특징은 아래와 같다.

  • 코드의 중복을 최소화 한다.
  • 상속과 달리 필요한 것만 골라서 사용할수 있으며 참조추적 비용이 없어 가볍다
  • 값 타입도 상속처럼 공통된 기능을 쉽게 구현할 수 있다
  • Class 는 하나의 상속만 가능하고 수직적인 구조이지만 Protocol을 사용하면 수평적인 확장이 가능해진다
  • generic을 활용하여 자료형에 구애받지 않는 범용 코드를 작성할 수 있다.

POP를 적극 활용하면 상속을 지원하지 않는 struct에서도 다형성을 충분히 구현할 수 있게 된다.

// define a protocol for vehicles
protocol Vehicle {
    // define some properties
    var currentSpeed: Double { get set }

    // define some methods
    func start()
    func stop()
}

extension Vehicle {
    func start() {
        print("Starting...")
    }

    func stop() {
        print("Stopping...")
    }
}

struct Car: Vehicle {
    var currentSpeed = 0.0

    mutating func stop() {
        print("Stopping...(overriding)")
        currentSpeed = 0
    }

    func honk() {
        print("Beep beep!")
    }
}

var car = Car()

car1.start() // "Starting..."
car1.stop() // "Stopping...(overriding)"

car1.honk() // "Beep beep!"

📝 참고 사이트

Categories:

Updated:

Leave a comment