はじめに (対象読者・この記事でわかること)

本記事は、Swift を使って iOS アプリや macOS アプリを開発している初心者〜中級者のプログラマを対象としています。特に「2 次元配列を作りたいが、コンパイルエラーが出てしまう」経験がある方に向け、エラーの根本原因と適切な初期化方法を具体的なコード例と共に解説します。この記事を読むことで、次のことができるようになります。

  • 2 次元配列の正しい型指定と初期化方法を理解する
  • コンパイルエラーのメッセージを正しく読み取り、原因を特定できる
  • 実務で頻出する「サイズが固定されていない」配列の作り方をマスターできる

記事執筆のきっかけは、社内勉強会で多数報告された「[[Int]] の初期化がうまくいかない」問題です。実際に遭遇したエラー例と解決策をまとめ、同じ壁にぶつかる開発者の時間を削減したいと考えました。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。

  • Swift の基本的な文法(変数宣言、型推論、リテラル)
  • Xcode のビルド/デバッグの基本操作
  • 配列(Array)の一次元での使用経験

2次元配列初期化の概要と典型的なエラー

Swift では、一次元配列はリテラル [1, 2, 3] だけで簡単に作れますが、二次元以上になると「要素の型が不明」や「空配列の型推論ができない」などのコンパイルエラーが頻発します。代表的なエラーは次の 2 パターンです。

  1. 空の二次元配列を var matrix = [] と書いたとき
    Swift は [] の要素型を推測できないため、Cannot infer type of array literal というエラーが出ます。

  2. サイズが揃っていないリテラルをそのまま書いたとき
    例: let matrix = [[1, 2], [3, 4, 5]]
    要素数が揃っていないと、Invalid redeclaration of 'matrix'Type of expression is ambiguous without more context が発生しやすいです。

これらは「型が曖昧」や「リテラルだけでは情報が足りない」ことが根本原因です。Swift の型システムは静的で厳格なため、コンパイル時に正確な型情報が必要となります。

実装例とエラー回避の手順

以下では、実際に Xcode の Playground やプロジェクトで使える 2 次元配列の初期化パターンをステップごとに紹介します。各ステップで起こりうるエラーと、その解決策を併せて説明します。

ステップ 1: 型注釈を付けて空配列を作る

Swift
// 型注釈を明示すると空配列でもエラーにならない var emptyMatrix: [[Int]] = []

ポイント
- [[Int]] と二重の角括弧で「配列の配列」=二次元配列であることを明示します。
- この書き方であれば、後から append で要素を追加できます。

ハマりやすい点
- 型注釈を忘れると [] の型が不明でエラーになる。
- Array<Array<Int>> と書いても同様に認識できますが、[[Int]] の方が可読性が高いです。

ステップ 2: 定数でサイズ固定の二次元配列を作る(リテラル方式)

Swift
let fixedMatrix: [[Int]] = [ [0, 0, 0], [0, 0, 0], [0, 0, 0] ]

ポイント
- 行と列の要素数が揃っているので、型推論が正しく働きます。
- let にすることで不変(immutable)となり、意図しない書き換えを防げます。

ハマりやすい点
- 行ごとに要素数が揃っていないとコンパイルエラーになる。
- リテラル内で数値が混在すると型が揃わず、[Int][Double] が混ざると [[Any]] になり、予期せぬ型になることがあります。

ステップ 3: repeating イニシャライザで同一サイズの配列を生成

Swift
let rows = 4 let cols = 5 let zeroMatrix = Array(repeating: Array(repeating: 0, count: cols), count: rows)

ポイント
- Array(repeating:count:) を二重に使うことで、すべての要素が 0rows × cols 行列が一瞬で作れます。
- 可変にしたい場合は var zeroMatrix = ... と宣言し、後から要素を書き換えれば OK。

ハマりやすい点
- repeating に渡す配列が参照型(例えば class インスタンス)だと、全行が同一インスタンスへの参照になるため、1 行を書き換えると全行が変化してしまう点に注意が必要です。
- 基本型(Int, String など)であれば問題ありません。

ステップ 4: mapjoined を組み合わせて可変長の二次元配列を作る

Swift
let data = ["1,2,3", "4,5,6", "7,8,9"] let matrix = data.map { line in line.split(separator: ",").compactMap { Int($0) } }

ポイント
- CSV など文字列データから二次元配列を生成したいときに便利。
- compactMap で文字列 → Int の変換エラーを除外できます。

ハマりやすい点
- 文字列が数値に変換できない場合は nil が除外され、行の要素数が変わってしまうため、サイズチェックが別途必要です。
- 行ごとに要素数が異なると、結果は「ジャグ配列」になる点に注意。

ハマった点やエラー解決

発生したエラー 原因 解決策
Cannot infer type of array literal 空配列に型注釈が無い var matrix: [[Int]] = [] と明示的に型を書く
Type of expression is ambiguous without more context リテラルの要素数が揃っていない、または混在型 行ごとに要素数を統一し、型を揃える(全て Int に統一)
Array element is not a literal repeating に参照型オブジェクトを渡した 参照型の場合は map で個別インスタンスを生成するか、struct に変更

解決策まとめ

  1. 型注釈を必ず付与:空の二次元配列を作るときは [[要素型]] を明示。
  2. 要素数を統一:リテラルで書く場合は各行の要素数を合わせる。
  3. repeating の使いどころ:基本型の初期化に適し、参照型は注意が必要。
  4. 文字列からの変換mapcompactMap で安全に変換し、サイズチェックは別途実装。

まとめ

本記事では、Swift における 2 次元配列の初期化でよく遭遇するコンパイルエラーの原因と、具体的な回避策を 4 つの実装パターンエラー事例表 を交えて解説しました。

  • 型注釈が無いと空配列はコンパイルエラーになる
  • 行ごとの要素数が揃っていないと型推論が失敗する
  • Array(repeating:count:) は基本型に最適で、参照型は注意が必要
  • 文字列データからの変換は mapcompactMap が便利だが、サイズチェックは別途必要

これにより、読者は「2 次元配列の作り方が分からない」状態から、正しい初期化コードを書き、エラーを即座に解決できる スキルを身につけられます。今後は、2 次元配列を使った行列演算やデータ可視化への応用例を別記事で取り上げる予定です。

参考資料