Day 8 ~ Day 9 : 구조체

sun·2021년 9월 17일
0

100 Days of SwiftUI

목록 보기
4/11

[Day 8]   [Day 9]

@ Day 8

# 구조체

struct User {
    var name: String
    var age: Int
    var city: String
}

var sun = User(name: "sun", age: 20, city: "Seoul")
print(sun.name)  // sun
print(sun.age)  // 20

# 연산 프로퍼티(Computed properties)

struct User {
    var name: String
    var age: Int
    var city: String
    var isAdult: Bool {
        if age >= 20 {
            return true
        } else {
            return false
        }
    }
}

var sun = User(name: "sun", age: 19, city: "Seoul")
print(sun.isAdult)  // true
sun.age = 20
print(sun.isAdult)  // false

# 프로퍼티 옵저버(Property observers)

  • 프로퍼티가 바뀌기 전에 특정 코드를 실행하고 싶다면 willSet ,
    바뀐 후에 실행하고 싶다면 didSet 사용
struct Progress {
    var task: String
    var amount: Int {
        didSet {
            print("\(task) is now \(amount)% complete")
        }
    }
}

var progress = Progress(task: "Loading data", amount: 0)
progress.amount = 30  // Loading data is now 30% complete
progress.amount = 80  // Loading data is now 80% complete
progress.amount = 100  // Loading data is now 100% complete

# 메서드(Methods)

  • 특정 타입 내부에서
    func methodName(parameter...) -> returnType {//some code}
    와 같이 선언
struct City {
    var population: Int
    
    func collectTaxes() -> Int {
        return population * 1000
    }
}

let seoul = City(population: 100)
print(london.collectTaxes())  // 100,000 

함수 vs 메서드 ?

메서드는 구조체, 열거형, 클래스 등 특정 타입에 속한다는 점을 빼면 함수와 같음

    ☝️ 대신 메서드는 자신이 속한 타입 의 다른 프로퍼티메서드 에 접근 가능


# Mutating Methods

  • 구조체 내부의 프로퍼티 값을 변경하는 메서드 앞에는 mutating 을 표기해줘야 함
  • mutating 함수를 호출하는 메서드 또한 mutating method 이어야 함
  • var 로 선언된 인스턴스인 경우에만 mutating method 호출 가능
struct Person {
    var name: String
    
    mutating func makeAnonymous() {
        name = "Anonymous"
    }
}

var person = Person(name: "sun")
person.makeAnonymous()
print(person.name)  // Anonymous

@ Day 9

# 이니셜라이저(생성자, Initializer)

  • 구조체의 경우 기본적으로 인스턴스 생성 시 memberwise initializer가 있음
struct User {
    var username: String
}

var user = User(username: "sun")  // memberwise initializer
  • 이와 별도로 구조체 내부에 init(){} 을 선언해 custom initializer 를 만들어 사용할 수 있음
  • 단 custom initializer 를 사용하는 경우 memberwise initializer 는 불가
struct User {
    var username: String
    
    init() {
        username = "Anonymous"
        print("Creating a new user!")
    }
}

var user = User()  // OK
user.username = "sun"

var user2 = User(username: "sun")  // KO : ERROR

# self.

  • 이니셜라이저 내부에서 현재 인스턴스의 프로퍼티를 지칭할 때 self. 키워드를 사용할 수 있음
struct Person {
    var name: String
    
    init(name: String) {
        print("\(name) was born!")
        self.name = name
    }
}

# Lazy

  • Lazy 키워드를 프로퍼티 앞에 붙이면 해당 프로퍼티는 실제로 해당 프로퍼티에 (최초로) 접근이 이루어질 때 생성됨
struct FamilyTree {
    init() {
        print("Creating family tree!")
    }
}

struct Person {
    var name: String
    lazy var familyTree = FamilyTree()
    
    init(name: String) {
        self.name = name
    }
}

var sun = Person(name: "Sun")  // sun.familyTree does not exist
sun.familyTree  // sun.familyTree now exists

# 정적 프로퍼티와 메서드

  • 구조체의 프로퍼티나 메서드를 정적으로 선언하면 해당 구조체의 모든 인스턴스에서 공유 가능
  • nameOfStruct.staticProperty 로 호출
struct Student {
    static var classSize = 0
    var name: String
    
    init(name: String) {
        self.name = name
        Student.classSize += 1
    }
}

var sun = Student(name: "Sun")
var moon = Student(name: "Moon")
var start = Student(name: "Star")
print(Student.classSize)  // 3

# 접근 제어(Access control)

  • 프로퍼티/메서드 앞에 private 키워드를 붙이면 해당 인스턴스 내부에서만 접근 가능
struct Person {
    private var id: String
    
    init(id: String) {
        self.id = id
    }
    
    func identify() -> String {
        return "My social security number is \(id)"
    }
}

let sun = Person(id: "12345")
sun.identify()  // My social security number is 12345
print(sun.id)  // KO : ERROR
profile
☀️

0개의 댓글