構造体・クラス・列挙型
構造体
値型の一種。ストアドプロパティの組み合わせで、一つの値を示す。 構造体のプロパティを変更することは、その構造体を別の値にすることであり、変数への再代入が必要である。
struct User { let name = "Murata" let age = 20 }
定数のストアドプロパティは変更できない。
struct User { var name = "Murata" var age = 20 } var user1 = User() user1.name = "123" let user2 = User() user2.name = "345" => コンパイルエラーになる
クラス
参照型のデータ構造。 構造体との違いは、1・参照型であること 2・継承ができること の2つである。
クラスに紐づく要素
クラスプロパティとクラスメソッドがある。スタティックプロパティ・スタティックメソッドとは違い、オーバーライドができる。
class User { class var name: String { return "bakuro" } class func printUser() { print("this is class method") } } print(User.name) => bakuro User.printUser() => this is class method
列挙型
値型の一種で、複数の識別子をまとめる。それぞれのケースは排他的である。
enum Weekday { case monday case tuesday //... } let monday = Weekday.monday
一般的にWeekday.monday
のようにケース名を指定してインスタンスを生成する。イニシャライザを持つこともできる。
enum Weekday { case monday case tuesday // nilになるかもしれないので失敗可能イニシャライザ init?(name: String) { switch name { case "月": self = .monday case "火": self = .tuesday // switchは全てを網羅すること default: return nil } } } let monday = Weekday(name: "月") // Optional(Main.Weekday.monday) let tuesday = Weekday(name: "火") // Optional(Main.Weekday.tuesday) let sunday = Weekday(name: "日") // nil
また、メソッドやコンピューテッドプロパティを持つこともできる。
enum Weekday { case monday case tuesday func isDay() { print(true) } var japaneseName: String { switch self { case .monday: return "月曜日" case .tuesday: return "火曜日" } } }
実体の定義
列挙型のケースにはそれぞれ対応する値を設定できる。これをraw valueと呼ぶ。そして全てのケースのraw valueは同じであること。Int, String, Doubleなどを型に指定できる。また、暗黙的に失敗可能イニシャライザが用意され、対応するケースがあれば、そのケースはインスタンスにし、なければnilを返す。
enum 列挙型名 : ローバリューの型 { case ケース名1 = ローバリュー1 case ケース名2 = ローバリュー2 } // 例 enum Nation : String { case russia = "ロシア" case china = "中国" case korea = "朝鮮" } let n = Nation(rawValue: "ロシア") print(n) // Optional(Main.Nation.russia) // 失敗可能イニシャライザをもつので、「?」がいる。 print(n?.rawValue) // Optional("ロシア") let u = Nation(rawValue: "イタリア") // イタリアというローバリューに一致するケースがないので、nilがかえる。 print(u) // nil print(u?.rawValue) // nil
ローバリューのデフォルト値
Int, Stringではローバリューにデフォルト値があり、値を指定しない場合はデフォルト値が適用される。 Intなら、最初が0で1,2,3...と適用される。 Stringなら、ケース名がそのまま適用される。
enum Number : Int, CaseIterable { case zero case one case two } enum Alphabet : String, CaseIterable { case a case b case c } print(Number.zero.rawValue) // 0 print(Number.one.rawValue) // 1 print(Alphabet.a.rawValue) // a print(Alphabet.b.rawValue) // b // enumを, CaseIterableに準拠させるとallCasesによって、enumの全てのケースを配列で取得できる。 print(Number.allCases) //[Main.Number.zero, Main.Number.one, Main.Number.two] print(Alphabet.allCases) // [Main.Alphabet.a, Main.Alphabet.b, Main.Alphabet.c]