The Swift Programming Language 勉強記録 - 4
Swiftべんきょうきろく、その4、です。
Enumerations and Structures
列挙型を作りたいときはenumを使う。
一番シンプルな形は以下のような感じだろうか。
enum EnumTest { case Zero, One, Two, Three } EnumTest.Zero.hashValue // 0 EnumTest.One.hashValue // 1 EnumTest.Two.hashValue // 2 EnumTest.Three.hashValue // 3
hashValueには0から順番に値が割り当てられている。
型を指定してやると値を自分で割り当てることもでき、その場合はrawValueを使用することで値が取れる。
enum EnumTest: Int { case One = 1, Two, Four=4, Five, Ten=10 } // rawValueは割り当てた値 EnumTest.One.rawValue // 1 EnumTest.Two.rawValue // 2 EnumTest.Four.rawValue // 4 EnumTest.Five.rawValue // 5 EnumTest.Ten.rawValue // 10 // hashValueはデフォルトで設定された連番値 EnumTest.One.hashValue // 0 EnumTest.Two.hashValue // 1 EnumTest.Four.hashValue // 2 EnumTest.Five.hashValue // 3 EnumTest.Ten.hashValue // 4
関数も持たせることができる。
enum Rank: Int { case Ace = 1 case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten case Jack, Queen, King func simpleDescription() -> String { switch self { case .Ace: return "ace" case .Jack: return "jack" case .Queen: return "queen" case .King: return "king" default: return String(self.rawValue) } } func compare(rank: Rank) -> Int { let sub = self.rawValue - rank.rawValue if (sub == 0) { return sub } else if (sub < 0) { return -1 } else { return 1 } } } let king = Rank.King let kingRawValue = king.rawValue // 13 king.simpleDescription() // "king" Rank.Jack.compare(Rank.Ace) // 1 Rank.Jack.compare(king) // -1
イニシャライザを使用して列挙型のインスタンスを作成することも可能。
// Rank.Threeを作成 if let convertedRank = Rank(rawValue: 3) { let threeDescription = convertedRank.simpleDescription() // "3" convertedRank.rawValue // 3 } // Rankの中にrawValue=14のものはないので作成されない if let convertedRank = Rank(rawValue: 14) { let threeDescription = convertedRank.simpleDescription() convertedRank.rawValue } else { // else節が実行される println("Can't convert") }
構造体の宣言はstructキーワードを用いることで行う。
struct Card { var rank: Rank var suit: Suit func simpleDescription() -> String { return "The \(rank.simpleDescription()) of \(suit.simpleDescription())" } func createDeck() -> [Card] { var deck = [Card]() for suit in [Suit.Spades, Suit.Hearts, Suit.Diamonds, Suit.Clubs] { for rank in 1...13 { deck.append(Card(rank: Rank(rawValue: rank)!, suit: suit)) } } return deck } } let threeOfSpades = Card(rank: .Three, suit: .Spades) let threeOfSpadesDescription = threeOfSpades.simpleDescription() for card in threeOfSpades.createDeck() { println(card.simpleDescription()) }
構造体はクラスの持つ振る舞い(メソッドやイニシャライザを持つなど)のほとんどをサポートしているが、構造体は値として構造体のコピーそのものを格納する値型であるのに対し、クラスはデータへの参照を持つ参照型であるという重要な違いを持つ。
あと、列挙型にはAssociated Values(関連値)という仕組みも提供されている。
enum ServerResponse { // 関連値 case Result(String, String) case Error(String) } let successRes = ServerResponse.Result("6:00 am", "8:09 pm") let errorRes = ServerResponse.Error("Out of cheese.") func printResponseMsg(res: ServerResponse) { switch res { case let .Result(sunrise, sunset): let serverResponse = "Sunrise is at \(sunrise) and sunset is at \(sunset)." case let .Error(error): let serverResponse = "Failure... \(error)" } } printResponseMsg(successRes) // "Sunrise is at 6:00 am and sunset is at 8:09 pm." printResponseMsg(errorRes) // "Failure... Out of cheese."
第4回目、いじょーです。
関連値については「こういう書き方もできるんだー」くらいで、まだ理解が浅いな。。。
使いドコロとか追々おさえていけたらと思います。