SubscriptsはSwiftにおいて、配列や辞書と同様の方法でキーやインデックスで型の値にアクセスを提供することを可能にしますが、任意の独自のタイプに対してです。構文は関数に似ていますが、アクセスは括弧内で行います:object[key]。
特徴:
getのみ、またはgetとsetを含む)。適用:
例: 二次元配列(行列)と二つのパラメータを持つsubscript:
struct Matrix { let rows: Int, columns: Int private var grid: [Double] init(rows: Int, columns: Int) { self.rows = rows self.columns = columns grid = Array(repeating: 0.0, count: rows * columns) } subscript(row: Int, column: Int) -> Double { get { precondition(isValid(row: row, column: column), "インデックスが範囲外です") return grid[(row * columns) + column] } set { precondition(isValid(row: row, column: column), "インデックスが範囲外です") grid[(row * columns) + column] = newValue } } private func isValid(row: Int, column: Int) -> Bool { return row >= 0 && row < rows && column >= 0 && column < columns } } var matrix = Matrix(rows: 2, columns: 2) matrix[0,1] = 5.0 print(matrix[0,1]) // 5.0
subscriptはinout型のパラメータを持つことができますか?また、構造体でmutatingにすることは可能ですか?
答え:
inoutにはできません。mutating setとして宣言可能で、set内でselfを変更することができます:struct Counter { var value: Int = 0 subscript(increment: Bool) -> Int { mutating get { value += increment ? 1 : -1 return value } } }
ストーリー
カスタムコレクションでsubscriptのsetをmutatingとして定義し忘れたため、subscriptを通じて要素を変更しようとするとコンパイルエラーが発生しました。このエラーは長時間のデバッグの後、コレクションの統合ステージで現れました。
ストーリー
カスタムsubscriptでインデックスの範囲外に関する正しい処理を実装しなかったため、範囲外へのアクセスでクラッシュが発生しました。その結果、ビジネスクリティカルなデータ処理機能が落ちました。
ストーリー
キャッシュ用にenumで二つのパラメータを持つsubscriptを実装しましたが、subscriptは静的(型の)ではなく、インスタンスに対してのみ実装可能であることを考慮しませんでした。アーキテクチャの決定は誤りで、コレクションのAPI相互作用を再作成する必要がありました。