[Swift] Day8 - Structs, part one

한철희·2023년 2월 27일
0

100 DaysOfSwift

목록 보기
4/11

벌써 Struct순서네요.
구조체라고도 하는데 클로저와 마찬가지로 스위프트에서 중요합니다
우리만의 데이터구조를 만들게 해주고 이게 실제 프로젝트에서도 유용하거든요
오늘도 힘차게 가봅시다!


Creating your own structs

Swift에서는 2가지 방법을 제시하는데요 그 중 가장 흔한 방법이 structures 또는 그냥 struct라고도 합니다.
struct는 자신만의 변수, 상수, 함수를 만들 수 있으며 우리가 원하는대로 사용할 수 있슴다

Sport라는 간단한 예시를 볼건데요 nameString타입으로 저장하는 struct입니다.
참고로 struct안의 변수들은 properties(프로퍼티)라고 불립니다.
그럼 Sport는 하나의 프로퍼티를 가지는 구조체겠네요

struct Sport {
	var name: String
}

생각보다 간단하죠? struct키워드를 써주고 그 다음에 이름을 써주면 됩니다
{}내부에는 변수이름:타입을 작성하면 되구요
그럼이제 인스턴스를 생성해 볼까요?

var tennis = Sport(name: "Tennis")
print(tennis.name)

nametennis 둘 다 변수이기 때문에 물론 변경할 수도 있어요

tennis.name = "Lawn tennis"

프로퍼티는 일반 변수처럼 기본값을 가질 수도 있고 타입추론도 가능합니다.

값이 바뀌는것도 확인해 봤습니다


Computed properties

앞에서 Sport를 생성했죠?

struct Sport {
    var name: String
}

name이라는 String타입의 프로퍼티를 가지고 있습니다.
이걸 stored property(저장 프로퍼티)라고 합니다.
그리고 Swift에는 computed property(연산 프로퍼티)도 존재합니다

Sport에 저장 프로퍼티를 하나 더 추가하여 연산 프로퍼티의 작동도 확인해보죠

struct Sport {
    var name: String
    var isOlympicSport: Bool
    
    var olympicStatus: String {
        if isOlympicSport {
            return "\(name) is an Olympic sport"
        } else {
            return "\(name) is not an Olympic sport"
        }
    }
}

isOlympicSport라는 저장 프로퍼티와 olympicStatus 연산 프로퍼티를 추가해줬습니다.
olympicStatus은 일반적인 String변수처럼 보이지만 다른 프로퍼티 값에 따라서 다른 값을 반환합니다.

이걸 실제로 확인해보려면 새 인스턴스를 생성해보면 됩니다.

let chessBoxing = Sport(name: "Chessboxing", isOlympicSport: false)
print(chessBoxing.olympicStatus)

isOlympicSport가 false 값을 가지기 때문에 else 구문이 실행되네요


Property observers

프로퍼티 옵저버는 아무 프로퍼티에 변화가 생기기 전이나 후에 코드가 작동하도록 합니다. Progress 라는 struct를 통해 어떻게 작동하는지 살펴보죠

struct Progress {
    var task: String
    var amount: Int
}

이제 인스턴스를 생성할 수 있죠.
그 뒤에 값을 조정해보죠

var progress = Progress(task: "Loading data", amount: 0)
progress.amount = 30
progress.amount = 80
progress.amount = 100

여기서 우리가 하고자 하는것은 Swift가 amount의 값이 변할 때마다 message를 출력하게 하는겁니다.
이걸 didSet이라는 프로퍼티 옵저버를 통해 해보죠
amount값이 변할때마다 작성된 코드를 출력할겁니다

struct Progress {
    var task: String
    var amount: Int {
        didSet {
            print("\(task) is now \(amount)% complete")
        }
    }
}

실제로 확인해보면 amount이 값이 30, 80, 100으로 변할때마다
didSet에 있는 print()함수가 잘 작동하네요.
추가로 willSet이라는 키워드로 프로퍼티가 변하기 전에 작동하도록 할 수도 있지만 잘 사용되지는 않습니다


Methods

구조체안에는 함수도 작성할 수 있슴다. 그리고 그 함수들은 필요하다면 구조체의 프로퍼티를 사용할 수도 있죠
프로퍼티 내부의 함수는 똑같이 func키워드로 만들지만
이름은 method라고 불립니다.

City라는 구조체로 확인해보죠

struct City {
    var population: Int

    func collectTaxes() -> Int {
        return population * 1000
    }
}

population이라는 프로퍼티를 가지고 collectTaxes()메소드가 있네요
이 메소드는 City내부의 population 프로퍼티의 값을 1000배 해서 반환합니다.

let london = City(population: 9_000_000)
london.collectTaxes()

메소드 또한 구조체내부에 있기 때문에 위처럼 호출해서 사용해야 합니다

숫자에 쓰인_는 단순히 자리수를 구분하는 용도입니다


Mutating methods

만약 구조체에 프로퍼티가 변수인데, 인스턴스가 상수로 생성되면 그 프로퍼티는 변경할 수가 없어요. 또한 모든 프로퍼티가 상수가 되어버린답니다 만들어진 방식에 상관없이요

문제는 구조체를 만들었을 때 Swift는 우리가 그것을 변수로 사용할지 상수로 사용할 지 알 수 없다는거죠. 그래서 기본 접근법으로 안전한 방식을 취합니다. 스위프트는 우리가 특별히 요구하지 않는 이상은 프로퍼티를 변경하는 메소드를 작성하게 해주지 않슴다

메소드안의 프로퍼티를 변경하고 싶다면 mutating이라는 키워드로 마킹을 해줘야합니다

struct Person {
	var name: String
    
    mutating func makeAnonymous() {
    	name = "Anonymous"
    }
}

Because it changes the property, Swift will only allow that method to be called on Person instances that are variables

프로퍼티를 변경하기 때문에 스위프트는 변수인 Person 인스턴스에서만 사용할 수 있게합니다.

제대로 번역한게 맞는지 조금 헷갈려서 원본도 첨부합니다

var person = Person(name: "Ed")
person.makeAnonymous()

'Ed'로 되어있던 namemakeAnonymous() 메소드에 의해서 변경되었네요.


Properties and methods of strings

우리가 여태 String 타입들을 많이 사용했죠? 근데 애네도 struct랍니다
우리가 만드는 struct들처럼 String도 메소드와 프로퍼티를 가지고 있습니다. 이것들을 이용해서 String을 조작할 수 있어요

테스트용으로 쓸 String을 먼저 작성하죠

let string = "Do or do not, there is no try."
print(string.count)

count프로퍼티를 사용해서 string의 문자 개수를 알아낼 수 있어요

print(string.hasPrefix("Do"))

hasPrefix()은 특정한 문자로 string이 시작하면 '참'을 반환합니다

print(string.uppercased())

uppercased()메소드는 String을 대문자로 바꿔주고요

print(string.sorted())

sorted()는 문자들을 배열로 정리합니다

string.을 xcode에 입력하면 여러가지 다른 메소드나 프로퍼티들을 알 수 있어요


Properties and methods of arrays

'Array' 또한 구조체입니다. 이 말은 String과 마찬가지로 프로퍼티와 메소드를 이용해 조작할 수 있다는 말이죠

예시로 쓸 배열을 하나 선언해주고요

var toys = ["Woody"]
print(toys.count)

count로 배열 요소의 개수를 알아낼 수도 있고

toys.append("Buzz")

append()로 새로운 요소를 추가해 줄 수도 있죠

toys.firstIndex(of: "Buzz")

특정 요소의 인덱스를 firstIndex()를 통해 알아낼 수도 있죠
이 경우는 '1'을 출력하겠네요.

print(toys.sorted())

String과 마찬가지로 알파벳순서로 요소들을 정렬할 수도 있죠

toys.remove(at: 0)

마지막으로 요소를 삭제하고 싶다면 remove()를 사용하면 됩니다.

profile
초보 개발자 살아남기

0개의 댓글