ProgrammingiOS/Swift 開発者

Swiftにおけるサブスクリプトの動作、宣言と呼び出しのルール、通常のメソッドや計算型プロパティとの違いについて説明してください。

Hintsage AIアシスタントで面接を突破

回答。

質問の歴史:

サブスクリプトは、コレクションやデータ構造と安全に便利に操作するためにSwiftに導入され、コーナーブラケットの構文を使用して要素にアクセスできるようにします。

問題:

サブスクリプト、メソッド、計算型プロパティの混同及びそれらの適用範囲、コレクションでないデータへのアクセスや副作用のあるデータへの誤ったサブスクリプトの使用。

解決策:

サブスクリプトは、コーナーブラケットを使用してオブジェクトの要素へのアクセスを提供する特別なメカニズムです。読み取り専用または読み書き可能であり、IntだけでなくStringや独自の型など、あらゆる種類のパラメータをサポートします。

コードの例:

struct Matrix { private var data: [[Int]] init(rows: Int, columns: Int) { data = Array(repeating: Array(repeating: 0, count: columns), count: rows) } subscript(row: Int, column: Int) -> Int { get { data[row][column] } set { data[row][column] = newValue } } } var matrix = Matrix(rows: 2, columns: 2) matrix[0, 1] = 5 print(matrix[0, 1]) // 5

主要な特徴:

  • 必要に応じてサブスクリプトをオーバーロードでき、異なるパラメータで複数のものを作成できます。
  • メソッドとは異なり、サブスクリプトは常にコーナーブラケットを介して呼び出されます。
  • あらゆる型の値を返すことができ、読み取りと書き込みの両方をサポートします。

問題のある質問。

サブスクリプトは複数のパラメータを持てますか?

はい、サブスクリプトは任意のパラメータのセットと任意の型(例えば、タプル)を受け取ることができます。

コードの例:

// 上記のMatrixの例を参照してください (サブスクリプト(row: Int, column: Int))

読み取り専用のサブスクリプトを実装できますか?

はい、setを宣言しなければ、サブスクリプトは読み取り専用となります。

コードの例:

struct ReadOnlyArray { private let items = [1, 2, 3] subscript(index: Int) -> Int { return items[index] } }

サブスクリプトと計算型プロパティの違いは何ですか?

計算型プロパティは常に固定名を持ち、パラメータを受け取ることはありません。サブスクリプトは可変インデックスでアクセスすることができ、コレクション構造を模倣します。

一般的な誤りとアンチパターン

  • 副作用のある操作にサブスクリプトを使用する(例えば、グローバル変数を変更するなど)。
  • インデックスの範囲外に対する暗黙の処理(安全な動作の代わりにクラッシュする)。
  • 明示的な理由もなくサブスクリプトとメソッドを混同する。

実際の例

ネガティブケース

カスタム構造体でサブスクリプトがグローバル状態を変更するために使用され、配列内の要素に簡単にアクセスしただけで想定外の副作用を引き起こす。

利点:

  • 簡潔さ

欠点:

  • 明らかでない副作用
  • デバッグが難しい

ポジティブケース

サブスクリプトは、構造体内部のプライベート配列と連携するためのみに使用され、範囲外へのアクセスにはnilを返す処理が実装されています。

利点:

  • 論理的で安全
  • デバッグが容易
  • コードを読みやすい

欠点:

  • 必要に応じて明示的なエラーハンドリングを追加する必要がある。