10: structs

그루두·2024년 4월 18일
0

100 days of SwiftUI

목록 보기
15/108

100 days of swiftui: 10
https://www.hackingwithswift.com/100/swiftui/10

Struct

같은 구조를 가지는 데이터를 struct를 통해 만들 수 있다.

struct Player {
    let team: String
    var hp: Int
    
    func sayTeam() {
        print("My team is \(team).")
    }
    mutating func gotAttacked(attack: Int) {
        hp -= attack
        print("Now I have \(hp) hp.")
    }
}

예시로 바뀌지 않는 팀 소속을 가지고 있고, 변동하는 목숨을 가진 구조체를 위처럼 설정할 수 있다. 그리고 이 구조체는 자신의 팀을 프린트하는 sayTeam(), 공격을 받아 자신의 목숨을 공격만큼 잃는 gotAttacked(attack: In) 함수가 있다.

  • struct의 이름의 첫번째 문자는 대문자로 설정해야 한다. 필수는 아니지만 관습적으로 사용한다.
  • struct의 멤버 변수에 영향을 주는 함수는 앞에 mutating을 작성해야 한다.
  • struct 구조가 타입인 instance를 만들어 사용한다.
  • 상수인 instance는 var 타입의 속성이라도 수정할 수 없다.
  • .을 통해 instance의 속성(properties)에 접근한다.
let player1 = Player(team: "Mountain", hp: 30)
var player2 = Player(team: "Ocean", hp: 50)

print(player1.hp)
print(player2.team)

player1.sayTeam()
player2.gotAttacked(attack: 20)

결과:

30
Ocean
My team is Mountain.
Now I have 30 hp.

동적으로 구조체 안의 변수 설정하기

struct의 변수를 들어오는 값에 따라 자동으로 설정하고 값을 가져올 수 있다. 데이터이지만 함수처럼 동작하는 특징이 있다. 예시로 유급휴가 일 수가 정해져 있고, 사용한 휴가 일 수에 따라 남은 휴가 일 수를 설정하고 반환하는 아래 예시가 있다.

struct Employee {
    let name: String
    var vacationAllocated = 14
    var vacationTaken = 0

    var vacationRemaining: Int {
        get {
            vacationAllocated - vacationTaken
        }

        set {
            vacationAllocated = vacationTaken + newValue
        }
    }
}

var archer = Employee(name: "Sterling Archer", vacationAllocated: 14)
archer.vacationTaken += 4
archer.vacationRemaining = 5
print(archer.vacationAllocated)

archer라는 Employee를 정의한다.

  • 사용한 휴가 일만큼 vacationTaken 값을 증가시킨다. -> vacationRemaining get
  • 남은 휴가 일이 변경될 땐 vacatioinRemaining을 설정한다. -> vacationRemaining set (vacationAllocated가 이에 맞춰 변경된다)

결과:

9

퀴즈 속 예시

struct Wine {
	var age: Int
	var isVintage: Bool
	var price: Int {
		if isVintage {
			return age + 20
		} else {
			return age + 5
		}
	}
}
let malbec = Wine(age: 2, isVintage: true)
print(malbec.price)

코드 파일
https://github.com/soaringwave/Ios-studying/commit/a8653a50ecb22bac8b6516dc86b756c619516055

property obsevers: didSet, willSet

구조체 안의 변수가 변하기 전과 후에 실행되는 willSet과 didSet이 있다. 그리고 각각 oldValue, newValue를 사용해서 해당 변수의 값을 활용할 수 있다. 값이 변경될 때 다른 속성을 함께 변경해야 하거나 print 같이 추가 명령이 필요한 경우에 유용하게 쓸 수 있다.

struct Club {
    var members = ["me"] {
        willSet {
            print("Current members are: \(members)")
            print("New member will be: \(newValue)")
        }

        didSet {
            print("There are now \(members.count) members.")
            print("Former member list was \(oldValue)")
        }
    }
}

var knittinClub = Club()
knittinClub.members.append("Groo")
knittinClub.members.append("Cheese Cat")
knittinClub.members.append("White Elephant")

결과:

Current members are: ["me"]
New member will be: ["me", "Groo"]
There are now 2 members.
Former member list was ["me"]
Current members are: ["me", "Groo"]
New member will be: ["me", "Groo", "Cheese Cat"]
There are now 3 members.
Former member list was ["me", "Groo"]
Current members are: ["me", "Groo", "Cheese Cat"]
New member will be: ["me", "Groo", "Cheese Cat", "White Elephant"]
There are now 4 members.
Former member list was ["me", "Groo", "Cheese Cat"]

코드 파일
https://github.com/soaringwave/Ios-studying/commit/be551393ebb8f59b57b33ae96f97b63d1adebf6f

initializer

swift는 자동으로 struct의 initializer을 설정해줘서 memberwise initializer로 instance를 생성하면 된다. 하지만 내가 설정할 수도 있다. 모든 instance는 초기화(선언)할 때 멤버 데이터들을 모두 설정 완료해야 하니, initializer를 설정할 때는 이를 만족해야 한다.

예: Date 형태의 값을 받아 이를 String으로 변환해서 저장하는 struct

struct Time {
    var time: Date
    var timeString: String
    
    init(time: Date) {
        self.time = time
        timeString = time.formatted(date: .omitted, time: .standard)
    }
}

var time1 = Time(time: Date())
print(time1.timeString)

결과:

17:26:36

코드 파일
https://github.com/soaringwave/Ios-studying/commit/73b46d5324aaf203efbf911e5b402d1b6036a580

profile
계속 해보자

0개의 댓글

관련 채용 정보