はじめに (対象読者・この記事でわかること)
本記事は、Swift を使って iOS アプリや macOS アプリを開発している初心者〜中級者のプログラマを対象としています。特に「2 次元配列を作りたいが、コンパイルエラーが出てしまう」経験がある方に向け、エラーの根本原因と適切な初期化方法を具体的なコード例と共に解説します。この記事を読むことで、次のことができるようになります。
- 2 次元配列の正しい型指定と初期化方法を理解する
- コンパイルエラーのメッセージを正しく読み取り、原因を特定できる
- 実務で頻出する「サイズが固定されていない」配列の作り方をマスターできる
記事執筆のきっかけは、社内勉強会で多数報告された「[[Int]] の初期化がうまくいかない」問題です。実際に遭遇したエラー例と解決策をまとめ、同じ壁にぶつかる開発者の時間を削減したいと考えました。
前提知識
この記事を読み進める上で、以下の知識があるとスムーズです。
- Swift の基本的な文法(変数宣言、型推論、リテラル)
- Xcode のビルド/デバッグの基本操作
- 配列(
Array)の一次元での使用経験
2次元配列初期化の概要と典型的なエラー
Swift では、一次元配列はリテラル [1, 2, 3] だけで簡単に作れますが、二次元以上になると「要素の型が不明」や「空配列の型推論ができない」などのコンパイルエラーが頻発します。代表的なエラーは次の 2 パターンです。
-
空の二次元配列を
var matrix = []と書いたとき
Swift は[]の要素型を推測できないため、Cannot infer type of array literalというエラーが出ます。 -
サイズが揃っていないリテラルをそのまま書いたとき
例: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: 定数でサイズ固定の二次元配列を作る(リテラル方式)
Swiftlet fixedMatrix: [[Int]] = [ [0, 0, 0], [0, 0, 0], [0, 0, 0] ]
ポイント
- 行と列の要素数が揃っているので、型推論が正しく働きます。
- let にすることで不変(immutable)となり、意図しない書き換えを防げます。
ハマりやすい点
- 行ごとに要素数が揃っていないとコンパイルエラーになる。
- リテラル内で数値が混在すると型が揃わず、[Int] と [Double] が混ざると [[Any]] になり、予期せぬ型になることがあります。
ステップ 3: repeating イニシャライザで同一サイズの配列を生成
Swiftlet rows = 4 let cols = 5 let zeroMatrix = Array(repeating: Array(repeating: 0, count: cols), count: rows)
ポイント
- Array(repeating:count:) を二重に使うことで、すべての要素が 0 の rows × cols 行列が一瞬で作れます。
- 可変にしたい場合は var zeroMatrix = ... と宣言し、後から要素を書き換えれば OK。
ハマりやすい点
- repeating に渡す配列が参照型(例えば class インスタンス)だと、全行が同一インスタンスへの参照になるため、1 行を書き換えると全行が変化してしまう点に注意が必要です。
- 基本型(Int, String など)であれば問題ありません。
ステップ 4: map と joined を組み合わせて可変長の二次元配列を作る
Swiftlet 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 に変更 |
解決策まとめ
- 型注釈を必ず付与:空の二次元配列を作るときは
[[要素型]]を明示。 - 要素数を統一:リテラルで書く場合は各行の要素数を合わせる。
repeatingの使いどころ:基本型の初期化に適し、参照型は注意が必要。- 文字列からの変換:
mapとcompactMapで安全に変換し、サイズチェックは別途実装。
まとめ
本記事では、Swift における 2 次元配列の初期化でよく遭遇するコンパイルエラーの原因と、具体的な回避策を 4 つの実装パターン と エラー事例表 を交えて解説しました。
- 型注釈が無いと空配列はコンパイルエラーになる
- 行ごとの要素数が揃っていないと型推論が失敗する
Array(repeating:count:)は基本型に最適で、参照型は注意が必要- 文字列データからの変換は
mapとcompactMapが便利だが、サイズチェックは別途必要
これにより、読者は「2 次元配列の作り方が分からない」状態から、正しい初期化コードを書き、エラーを即座に解決できる スキルを身につけられます。今後は、2 次元配列を使った行列演算やデータ可視化への応用例を別記事で取り上げる予定です。
参考資料
- Swift Programming Language – Arrays
- Apple Developer Documentation – Initialization
- 「Swift実務入門」 (著者: 渡辺 修, 出版: 技術評論社)
- Stack Overflow – Swift 2D array initialization
