SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

アップルの新プログラミング言語「Swift」を探検しよう

Swiftの「クラス」と「ストラクチャ」 その② ~ subscript、タイプキャスト、メモリ管理(およびクラス、ストラクチャ、列挙型のおさらい)

アップルの新プログラミング言語「Swift」を探検しよう 第5回

  • このエントリーをはてなブックマークに追加

 前回はクラスとストラクチャを中心にプロパティ、メソッド、継承、ライフサイクルの解説をしました。今回はsubscript、アクセス修飾子、タイプキャスト、ARCによるメモリ管理を中心に解説した後、クラス、ストラクチャ、列挙型のおさらいをします。

  • このエントリーをはてなブックマークに追加

subscriptキーワード

 本連載第1回で取り上げたArray、Dictionaryには、次のように [] で中身にアクセスしたり更新したりする機能が備わっていました。

var animals = ["dog", "cat", "elephant"] // [String]
animals[1] // "cat"を取得
var countries = ["JPN" : "Japan", "USA" : "America"] // [String: String]
countries["USA"] = "United States" // "USA"のキーに対応する値を更新

 この機能をsubscriptといいます。自分で作成した型にsubscriptを宣言することでArrayのような[]を通じての中身のアクセスや更新の機能をカスタマイズすることができます。また、[]に入れる中身の型を変えることでsubscriptのオーバーロードを行うことも可能です。

 subscriptの宣言方法は、プロパティのget/setとメソッドを組み合わせたような構文をとります。

subscript(引数のリスト) -> 返り値 {
    get {
        文
        return 返り値
    }
    set(新たな値) {
        新たにセットされた値を元に計算
    }
}

 宣言の例を見てみましょう。

struct Page {
    let numberOfLines: Int
    let numberOfCols: Int

    private var contents: [String]

    init (numberOfLines: Int, numberOfCols: Int) {
        self.numberOfLines = numberOfLines
        self.numberOfCols = numberOfCols
        let emptyLine = String(count: numberOfCols, repeatedValue: " " as Character)
        self.contents = Array(count:numberOfLines, repeatedValue:emptyLine)
    }

    subscript(line: Int) -> String {
        get {
            return contents[line]
        }
        set (newLineContent) {
            let newContentCols: Int = countElements(newLineContent)
            if newContentCols <= numberOfCols {
                let newLine = newLineContent + String(count:numberOfCols - newContentCols, repeatedValue:" " as Character)
                contents[line] = newLine
            }
        }
    }
}

var somePage = Page(numberOfLines: 4, numberOfCols: 10)
somePage[1] // "          "
somePage[1] = "content"
somePage[1] // "content   "

 このサンプルコードは本のページを表したもので、行数と1行に入る文字数を指定できます。

 subscriptキーワードの後にはメソッドの引数リストと、返り値の宣言のように [] の中に渡したい引数の型のリスト、および代入と取得をしたい型を記述します(private修飾子は次の節で解説します)。 その後で、計算プロパティのget/setの宣言のように、getとsetで取得時および代入時の操作を記述します。

 なお、この例では [] の中で引数を1つしか渡していませんが、次のようにsubscriptを宣言することで、引数を2つ渡すこともできます。

struct Book {
    let name: String
    let numberOfPages: Int
    let numberOfLines: Int
    let numberOfCols: Int

    private var contents: [Page]

    init (name: String, numberOfPages: Int, numberOfLines: Int, numberOfCols: Int) {
        self.name = name
        self.numberOfPages = numberOfPages
        self.numberOfLines = numberOfLines
        self.numberOfCols = numberOfCols

        let emptyPage = Page(numberOfLines: numberOfLines, numberOfCols: numberOfCols)
        self.contents = Array(count:numberOfPages, repeatedValue:emptyPage)
    }

    subscript(page: Int, line: Int) -> String {
        get {
            return contents[page][line]
        }
        set {
            contents[page][line] = newValue
        }
    }
}

var someBook =
Book(name: "some",
    numberOfPages: 4,
    numberOfLines: 40,
    numberOfCols: 20)

someBook[1, 2] // "                    "
someBook[1, 2] = "p one l2 content"
someBook[1, 2] // "p one l2 content    "

 このサンプルコードは本を表したもので、本の名前とページ数、およびページの行数と1行に入る文字数を指定できます。

 subscriptは、Optional列挙型を返すときにはメソッドのようにみなして、オプショナルチェイニング[1]することも可能です。

struct BookShelf {
    private var books: [String: Book]
    init (books: Book...) {
        var bookDict: [String: Book] = Dictionary()
        for book in books {
            bookDict[book.name] = book
        }
        self.books = bookDict
    }

    subscript(name: String) -> Book? {
        return books[name]
    }
}

var bookShelf = BookShelf(books: someBook)
bookShelf["some"]?[1, 2] // "p one l2 content    "
bookShelf["any"]?[1, 2]  // nil

 このサンプルコードは本棚を表したもので、本の名前をキーにして本を貯めこむことができます。

[1] オプショナル列挙型を返すメソッドやプロパティを「.」(ピリオド)つなぎで次々に呼び出していくことです。「.」の前に「?」を置くことでそれが可能になります。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
アクセス修飾子

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
アップルの新プログラミング言語「Swift」を探検しよう連載記事一覧

もっと読む

この記事の著者

yad(ヤド)

クラスメソッド株式会社のアプリケーションエンジニア。iPhoneアプリケーションの開発に2年以上従事している。開発に使用するObjective-Cのみならず、関数型言語Haskellや機械学習などにも関心がある。「Developers.IO」に寄稿した記事の一覧

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/8120 2014/09/29 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング