1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

タイプ・メソッドの利用法

Posted at

「詳解 Swift 改訂版」のChapter3、構造体のパートを読んで、構造体の「タイプ・メソッド」の復習をしていました。しかし、萩原さんの説明の矛盾点に悩んでいます。

タイプ・メソッド

  • タイプ・メソッドは、個々のインスタンス機能を実装するものではなく、全インスタンス共通して利用される機能の提供
  • インスタンスの作り方(個数の制限や再利用)のコントロール
  • この型を利用するうえで便利な機能の提供

タイプ・メソッドの説明があり、例文として次の構造体を挙げています。「static」キーワードが付いているメソッドがタイプ・メソッドで、2つ指定されています。「isLeap」メソッドは「うるう年」かどうか判定する計算式です。「西暦年が4で割り切れる年ですが、100で割り切れない年でないといけません。しかし、400で割り切れる場合はうるう年になります」なので、式にしたのが「isLeap」メソッド内の式です。

そして、ある年のある月が何日あるか返すメソッドが「daysOfMonth」メソッドです。これはisLeapメソッドを利用しています。

swift3
struct Date {
    var year, month, 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(y: year) ? 29 : 28
        case 4, 6, 9, 11: return 30
        default: return 31
        }
    }
}

さて、悩んでいるのはこのタイプメソッドの利用法です。萩原さんは次のコードを載せています。

swift3
Date.isLeap(y: 2000)               // trueが返る
Date.daysOfMonth(m: 2, year: 2000) // 29が返る

実はこういう利用法は、上記のタイプ・メソッドの説明に合ってないから納得できないんです。最初の説明に書いているように「全インスタンス共通して利用される機能の提供」として考えるなら、次のような例文の方が合っているような気がします。

swift3
var someDate = Date(year: 2050, month: 11, day: 29)
var anyDate = Date(year: 2016, month: 1, day: 17)

// 上記のようにインスタンスを作って、
// これに共通する機能として次のように書く方が
// 望ましいんじゃないでしょうか? 

Date.isLeap(y: anyDate.year)     // trueが返る
Date.isLeap(y: someDate.year)    // falseが返る

萩原さんの利用法で説明するのなら、**構造体Dateのプロパティ「year」「month」「day」が意味を成さないような気がします。**というのも、萩原さんの利用法を推奨するなら、次のような例文もできます。

swift3
var day = 31
Date.isLeap(y: day)

こうなってしまったら、タイプメソッドの説明とはかけ離れてしまいます。いっそのことプロパティを排除して、タイプ・メソッドだけで構成した次のような共通メソッド群とした方がいいような気がします。

swift3
struct ComonFunctions {
    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 isLeap(y: year) ? 29 : 28
        case 4, 6, 9, 11: return 30
        default: return 31
        }
    }
}

プログラマーの皆さん、どうなんでしょうか?

1
2
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?