はじめに
今回はメソッドやプロパティによってインスタンスの値が変更される場合に用いられる、mutatingと全てのインスタンスから共通して利用したい場合に用いられるstaticについてみていきましょう。
mutating
先ほど、メソッドやプロパティによってインスタンスの値が変更される場合に用いられる、mutatingと言いましたが、実はこれ、構造体(struct)についてのみつけるキーワードになります。つまり、クラスには必要ありません。
例を見ていきましょう。
struct Clock {
var hour = 0
var min = 0
mutating func advance(min: Int) {
let m = self.min + min
if m >= 60 {
self.min = m % 60 // インスタンスの値が変更されている
let t = self.hour + m / 60
self.hour = t % 24 // インスタンスの値が変更されている
} else {
self.min = m // インスタンスの値が変更されている
}
}
mutating func inc() {
self.advance(min: 1)
}
}
プロパティを直接書き換えるメソッドのadvance(min:)
にmutatingをつけています。さらに、そのメソッドを呼び出しているinc()
メソッドにもmutatingが必要です。
mutatingをつけていないと以下のようなエラーがでてきてしまいます。
static
staticがついたメソッドをタイプメソッドといいます。
staticは全てのインスタンスから共通して利用したい場合に用いられます。
struct SimpleDate {
var year: Int
var month: Int
var day: Int
static func isLeap(_ y: Int) -> Bool {
return (y % 4 == 0) && (y % 100 != 0 || y % 400 == 0)
}
static func daysOfMonth(_ m: Int, year: Int) -> Int {
switch m {
case 2: return Self.isLeap(year) ? 29 : 28 // isLeap(year)だけでもいい
case 4, 6, 9, 11: return 30
default: return 31
}
}
func leapYear() -> Bool {
return SimpleDate.isLeap(year) // 構造体名.タイプメソッド
}
}
staticのついたプロパティやメソッドにアクセスするときは、構造体名.タイプメソッド
などのようにしますが、同じ構造体内でstaticプロパティやメソッドどうしにアクセスする場合はSelf.タイプメソッド
やSelfの省略もできます。
//isLeapもdaysOfMonthもstaticで同じ構造体なので、構造体名やSelfは書かなくても良い
static func daysOfMonth(_ m: Int, year: Int) -> Int {
switch m {
case 2: return isLeap(year) ? 29 : 28
case 4, 6, 9, 11: return 30
default: return 31
}
}
しかし、daysOfMonth
メソッドのstaticをとると以下のようなエラーになり、Self.isLeap()
にするか、SimpleDate.isLeap()
にしないといけません。
同様の理由で、leapYear()
メソッドには構造体名またはSelfが必要になります。
おわりに
おわりです。