# Day 11 - Access control, static properties and methods, and checkpoint 6 ## How to limit access to internal data using access control - 有些property的值不想被struct外部讀寫,可以在前面加上 `private` ``` struct BankAccount { private var funds = 0 mutating func deposit(amount: Int) { funds += amount } mutating func withdraw(amount: Int) -> Bool { if funds >= amount { funds -= amount return true } else { return false } } } ``` - access control:管理property或method是否可以從外部存取 - 存取權種類 | 關鍵字 | 說明 | | -------- | -------- | | private | 不讓任何struct以外的地方使用 | | fileprivate | 不讓目前檔案以外的地方使用 | | public | 任何地方都可以使用 | | private(set) | 外部只能讀不能寫 | - 如果有特別指定存取權,通常也需要自訂initializer ### Optional: What’s the point of access control? - 有時候權限控制是用在不屬於你的code裡面,例如Apple的API,所以你必須遵守這些存取權 - 就算是自己可以更動的code,access control也讓我們知道一個值應該怎麼被使用,所以不會是無意義的 ## Static properties and methods - 將property或method標為 `static` 表示這些操作是針對 struct 本身,而非 instance,因此針對property操作的 method 不需要加上 `mutating` 也能正確執行 ``` struct School { static var studentCount = 0 static func add(student: String) { print("\(student) joined the school.") studentCount += 1 } } School.add(student: "Taylor") ``` - 不能在 static 的property或method裡針對 non-static操作;反之則可以 - 兩種 self 的含義 - `self`:struct 目前的 value - `Self`:struct 目前的 type - `static` 的 use case - 常用data ``` struct AppData { static let version = "1.3 beta 2" static let saveFilename = "settings.json" static let homeURL = "https://www.hackingwithswift.com" } ``` - 範例data ``` struct Employee { let username: String let password: String static let example = Employee(username: "cfeghi", password: "h4irfo0rce0ne") } ``` ## Summary: Structs - 我們可以用 `struct` 關鍵字創建自己的 struct - struct 可以有它們自己的 properties 和 methods - 如果一個 method 會更動到 struct 的 property,他必須要是 `mutating` 的 - struct 可以有 `stored` 和 `computed` properties - 我們可以附加 `didSet` 和 `willSet` (property observers)在property上 - Swift用所有struct的property名稱為它們產生initializer - 如果想要的話也可以用自訂的initializer覆蓋預設的 - 必須確保所有property都有initial value - access control限制什麼code能使用properties 和 methods - static properties 和 methods 是直接被附加在struct上的 ## Checkpoint 6 ### 題目 - 創建一個struct儲存一台車的資訊,包括: - 車型 - 座位數量 - 排檔 - 增加一個可以升檔/降檔的method - 考慮變數和權限控制 - 不允許無效的檔位,限制在1到10檔 ### 答案 ``` struct Car { static let model = "Toyota Yaris" static let numberOfSeats = 5 var currentGear: Int mutating func changeGears(gear: Int) { if gear < 1 { currentGear = 1 } else if gear > 10 { currentGear = 10 } else { currentGear = gear } } } var car = Car(currentGear: 10) print(car.currentGear) // 10 car.changeGears(gear: 5) print(car.currentGear) // 5 car.changeGears(gear: 0) print(car.currentGear) // 1 car.changeGears(gear: 11) print(car.currentGear) // 10 ```