이번 편의 목표: 번호, 제목, 가격을 구조체 하나의 값으로 묶고, 그 값을 복사해 원본과 분리합니다.

구조체는 값 타입입니다. 다른 변수에 넣으면 내용이 복사됩니다. 멤버를 바꾸는 메서드에는 mutating을 붙입니다. let으로 만든 구조체는 그 메서드를 호출할 수 없습니다.

Swift
struct Book {
    var id: Int
    var title: String
    var price: Int

    func label() -> String {
        "\(id) \(title) \(price)"
    }
}

var book = Book(id: 1, title: "개미", price: 12000)
var copy = book
copy.price = 9000
print(book.label())
print(copy.label())

Book(id:title:price:)는 멤버 이름으로 만들어지는 초기화 구문입니다. 직접 init을 적지 않아도 됩니다. 출력의 첫 줄 가격은 12000이고 둘째 줄은 9000입니다. copy를 바꿔도 book은 그대로입니다.

메서드가 자신의 멤버를 바꾸면 mutating을 붙입니다.

Swift
struct Shelf {
    var titles: [String] = []

    mutating func add(_ title: String) {
        titles.append(title)
    }
}

var shelf = Shelf()로 만든 뒤에만 add를 호출합니다. 구조체는 책처럼 값이 독립이어야 하는 데이터에 맞습니다. 화면의 상태처럼 여러 곳이 같은 대상을 봐야 하면 다음 편의 클래스를 검토합니다.

직접 해 보기

book의 제목을 공책으로, 가격을 1800으로 바꾼 새 값을 만들어 label을 출력하세요. 원래 book의 label은 개미와 12000을 유지해야 합니다.

해설

새 변수에 book을 넣은 뒤 그 변수의 title과 price만 바꿉니다. 구조체 대입은 복사므로 원래 book의 멤버는 바뀌지 않습니다.