8일차 - 21.06.15

수킴·2021년 6월 15일
0

100DaysOfSwift

목록 보기
9/37
post-thumbnail

학습키워드

  • structs
  • properties
  • methods

1. Creating your own structs

스위프트는 자신이 직접 구조체라는 타입을 만들 수 있습니다. 구조체에는 변수나 상수, 자체함수를 부여할 수 있고 마음대로 사용할 수 있습니다.

  • 구조체 내부의 변수를 property(속성)이라고 합니다.
  • 속성은 일반변수처럼 기본값을 가질 수 있습니다.
struct Sport {
    var name: String
}

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

tennis.name = "Lawn tennis"

구조체와 튜플의 차이점 ?

스위프트의 튜플은 하나의 변수에 여러 개의 다른 타입의 값을 저장할 수 있습니다. 구조체와 거의 동일합니다.

하지만 튜플은 여러번 사용하는 경우 튜플에 다른 값을 추가하거나 수정하는 경우 매우 번거롭습니다.

  • 예시

    // MARK : - 구조체 사용한 경우
    struct User {
        var name: String
        var age: Int
        var city: String
    }
    
    func authenticate(_ user: User) { ... }
    func showProfile(for user: User) { ... }
    func signOut(_ user: User) { ... }
    
    // MARK : - 튜플 사용한 경우
    func authenticate(_ user: (name: String, age: Int, city: String)) { ... }
    func showProfile(for user: (name: String, age: Int, city: String)) { ... }
    func signOut(_ user: (name: String, age: Int, city: String)) { ... }

2. Computed properties

스위프트는 stored properties(저장 프로퍼티)말고도 연산프로퍼티를 제공합니다. 연산 프로퍼티는 다른 프로퍼티를 사용하여 값을 반환할 수 있습니다.

  • 연산프로퍼티는 타입을 생략하면 안됩니다.
  • 연산프로퍼티는 상수로 선언할 수 없습니다.
  • 연산프로퍼티는 반환값이 있어야 합니다.
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"
        }
    }
    
    var computedProperty: String {
        return "computedProperty"
    }
}

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

// 실행 결과
Chessboxing is not an Olympic sport
computedProperty

언제 저장프로퍼티, 연산프로퍼티를 사용해야 할까?

저장프로퍼티는 값을 나중에 사용하기 위해 일부 메모리에 숨겨져있고 연산프로퍼티는 호출될 때마다 값이 다시 계산되는 특성이 있습니다. 따라서, 어떤 관점에서는 연산프로퍼티는 구조체에 속하는 함수호출로도 볼 수 있습니다.

이러한 특성을 생각하면, 값이 변경되지 않았을 때 프로퍼티를 계속해서 읽고 있다면 저장프로퍼티를 사용하는 것이 성능면에서 유리하고

반면에, 프로퍼티를 거의 읽지 않고 전혀 읽지 않는 경우 연산프로퍼티를 사용하는 것이 유리합니다. 또한 종속성을 생각하여 프로퍼티가 다른프로퍼티 값에 의존하는 경우에도 유용합니다.

3. Property observers

스위프트의 프로퍼티관찰자를 사용하면 프로퍼티가 변경 전후에 코드를 실행할 수 있습니다.

  • 프로퍼티 값이 변경 될 때마다 코드를 실행하기 위해서는 didSet 을 사용합니다.

  • 프로퍼티 값이 변경 되기전에 코드를 실행하기 위해서는 willSet 을 사용하지만 거의 사용되지 않습니다.

    → 값이 변경되기 전에 프로그램의 상태를 알아야할 때 사용

  • 모든 장소에서 값이 변경될 때마다 기능을 수행하지만 매번 바뀔 때마다 호출되기 때문에 이런 점을 주의해야 합니다.

❗️ 상수는 절대 변경되지 않기 때문에 프로퍼티 관찰자를 상수에 연결할 수 없습니다.

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

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

// 실행 결과
Loading data is now 30% complete
Loading data is now 80% complete
Loading data is now 100% complete

4. Methods

구조체는 내부의 함수를 가질 수 있으며 이러한 함수를 메서드라고 부릅니다.

메서드는 구조체 내부의 프로퍼티를 사용할 수 있습니다.

struct City {
    var population: Int

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

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

함수와 메서드의 차이점은 무엇인 가?

유일한 차이점은 메서드는 구조체, 열거형 및 클래스와 같은 유형에 속하지만 함수는 그렇지 않다는 것입니다.

메서드는 구조체의 프로퍼티를 참조할 수 있고 이름을 작성할 때 예약어로 정의되지 않고 구조체에 속한 예약어가 되기 때문에 여러 이름을 작성할 수 있는 이점이 있습니다.

5. Mutating methods

구조체에는 변수 속성이 있지만 구조체는 상수로 인스턴스가 생성된 경우 해당 속성을 변경할 수 없습니다. 따라서 스위프트는 특별히 요청하지 않는 한 속성을 변경하는 메서드를 작성하도록 허용하지 않습니다.

struct Person {
    var name: String

    mutating func makeAnonymous() {
        name = "Anonymous"
    }
}

var person = Person(name: "hey")
person.name // hey
person.makeAnonymous()
person.name // Anonymous
  • mutating 키워드를 사용해도 구조체 인스턴스를 상수로 선언한 경우 에러가 발생
  • mutating 키워드가 사용되는 이유는 스위프트가 구조체인스턴스가 상수로 되었는데 속성을 변경할 떄 접근을 방지하도록 알려주기 위해서입니다.

6. Properties and methods of strings

스위프트에서 문자열의 타입은 구조체로 작성되어 있습니다. 따라서, 문자열은 자체 메서드와 속성을 가지고 있습니다.

let string = "Do or do not, there is no try."

print(string.count) // count속성을 사용하여 문자열의 문자 수를 알 수 있습니다.
print(string.hasPrefix("Do")) // hasPrefix()메서드를 사용하여 특정 문자로 시작하면 true를 반환합니다.
print(string.uppercased()) // uppercased()메서드는 문자열을 대문자로 변경해줍니다.
print(string.sorted()) // sorted()메서드는 문자열의 문자를 배열로 정렬해줍니다.

// 실행결과
30
true
DO OR DO NOT, THERE IS NO TRY.
[" ", " ", " ", " ", " ", " ", " ", ",", ".", "D", "d", "e", "e", "h", "i", "n", "n", "o", "o", "o", "o", "o", "r", "r", "r", "s", "t", "t", "t", "y"]

스위프트에서 문자열을 구조체로 작성된 이유가 무엇인가?

다른 많은 언어에서는 문자열은 구조체로 작성되있지 않습니다. 스위프트의 타입 중 구조체로 작성된 타입은 Int, String, Array, Dictionary, Bool 등등이 있습니다.

문자열은 여러가지 언어와 이모티콘등등이 있습니다. 이러한 모든 문자들을 처리하는 경우 구조체를 사용하면 편리해집니다. → 스위프트의 문자열은 여러가지 문자처리의 복잡한 문제들을 편리하게 처리하도록 설계되어 있습니다.

7. Properties and methods of arrays

배열도 구조체로 작성되어 있기 때문에 사용할 수 있는 자체메서드와 속성이 있습니다.

var toys = ["Woody"]

print(toys.count) // 배열의 항목 수
toys.append("Buzz") // 새 항목을 추가
toys.firstIndex(of: "Buzz") // 배열 내부의 모든 항목을 찾을 수 있습니다
print(toys.sorted()) // 배열의 항목을 알파벳순으로 정렬
toys.remove(at: 0) // 배열의 항목을 제거

문자열이 스위프트의 배열과 다르게 동작하는 이유는 무엇인가?

어떻게 생각해보면 문자열은 문자들이 모인 배열 같지만 스위프트에서는 myString[3] 처럼 문자에 접근할 수 없습니다. 그 이유는 여러 특수 문자로 연속해서 구성된 이모티콘 및 기타 유사하게 복잡한 문자 때문입니다.

이모티콘 같은 경우 하나의 문자이지만 내부에서는 여러개의 문자가 응집되었을 때 제대로 해석됩니다.

링크

100 Days of Swift - Day 8 - Hacking with Swift

profile
iOS 공부 중 🧑🏻‍💻

0개의 댓글