
Swiftを始めよう! - Enum と構造体
Enumとは列挙体ということで、あるものを並べて示すということです。例えば
空、海、陸
東、西、北、南
など、何か関連のあるものを並べてひとまとまりで使うときに便利です。以下は基本的なもの。
enum CompassPoint {
case north
case south
case east
case west
}
取り出しは
var directionToHead = CompassPoint.west
Enumで使えるデータとしてはAssociated Values と Raw Valuesを定義することができます。
Raw Values
列挙型の識別子には識別子に値を持たせることができる。これをrawValueと呼ぶ。生の値。
識別子に値を持たせるものであり、識別子を別の値で利用するための手段と思って良い。つまり、代入可能な値ではない。
case ace = 1
のように代入して実際の値を入れるタイプ。
Associated Values
列挙型の識別子に関連した値(Associated Values)を持たせることもできる。
これまでのPlayingCardは内部にkindとrankをもたせた構造体で考えていたが、Associated Valuesを使うことで列挙型だけで管理することもできる。
代入ではなく、その識別子に関連した値を設定することができる。
case result(String, String)
のように型を示して定義するタイプ
以下例示のコードはトランプをひとまとめに""enum"で定義しています。カードをひとまとめに定義して、メソッドとして関数も定義しています。
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)
}
}
}
実行します。
let ace = Rank.ace
let aceRawValue = ace.rawValue
print(aceRawValue)
とすると"1"が出力されます。
case ace = 1
で定義されている"1"は"raw value"生のデータとして定義されます。
一つ定義しておくと。・・・ 以下"raw value"が定義されていませんが自動的に順番に"raw value"が与えられます。
case two, three, four, five, six, seven, eight, nine, ten
case jack, queen, king
two ・・・ 2
three ・・・ 3
・
・
king ・・・ 13
のように自動で番号がつきます。
if let convertedRank = Rank(rawValue: 3) {
let threeDescription = convertedRank.simpleDescription()
}
実行すると"3"が出ます。これを"Rank(rawValue: 1)"で実行すると"ace"が出てきます。関数"simpleDescription()"が実行されていることがわかります。
もし合致するものがない場合は"nil"となります。
"raw value"については必須ではないので以下のように定義することができます。
enum Suit {
case spades, hearts, diamonds, clubs
func simpleDescription() -> String {
switch self {
case .spades:
return "spades"
case .hearts:
return "hearts"
case .diamonds:
return "diamonds"
case .clubs:
return "clubs"
}
}
}
let hearts = Suit.hearts
let heartsDescription = hearts.simpleDescription()
switch内では".hearts"のように省略形で書くことができます。
raw valueは宣言された固定値となるが、associated valuesは関連した値を設置ができるためプロパティのように自由に変更が可能。以下associated values。
case result(String, String)
case failure(String)
コードの例示。
enum ServerResponse {
case result(String, String)
case failure(String)
}
let success = ServerResponse.result("6:00 am", "8:09 pm")
let failure = ServerResponse.failure("Out of cheese.")
switch success {
case let .result(sunrise, sunset):
print("Sunrise is at \(sunrise) and sunset is at \(sunset).")
case let .failure(message):
print("Failure... \(message)")
}
associated valuesの使い方は
let success = ServerResponse.result("6:00 am", "8:09 pm")
let failure = ServerResponse.failure("Out of cheese.")
場合分けします
switch success {
case let .result(sunrise, sunset):
print("Sunrise is at \(sunrise) and sunset is at \(sunset).")
case let .failure(message):
print("Failure... \(message)")
}
出力は
"Sunrise is at 6:00 am and sunset is at 8:09 pm."
構造体
struct Card {
var rank: Rank
var suit: Suit
func simpleDescription() -> String {
return "The \(rank.simpleDescription()) of \(suit.simpleDescription())"
}
}
let threeOfSpades = Card(rank: .three, suit: .spades)
let threeOfSpadesDescription = threeOfSpades.simpleDescription()
print(threeOfSpadesDescription)
出力すると。
The 3 of spades
struct を使用して構造体を作成します。 構造体は、メソッドや初期化子など、クラスと同じように機能します。 構造体とクラスの最も重要な違いの 1 つは、構造体はコード内で渡されるときに常にコピーされるのに対し(値渡し)、クラスは参照によって渡されることです(参照渡し)。
RankとSuitの2つのプロパティ、メソッドを持つ構造体。