コンパイルエラー集
読了目安 約4分
よく出るエラーメッセージ 12 個を、原因と直し方つきで引ける。
この章の目次
エラーが出たら、この章をメッセージで検索してください。 コンパイルエラーは実行前にコンパイラが見つけた間違い、実行時エラーは実行の途中でプログラムが止まる間違いです。
実際のメッセージの先頭には main.swift:2:14: のような場所情報が付きます。
数字は「2 行目の 14 文字目」という意味なので、まずその行を見てください。
実行時エラーは *** Swift runtime failure: ... *** のような 1 行で原因を示し、続くバックトレースの main.swift:2:23 が止まった場所です。
cannot find ‘x’ in scope
error: cannot find 'x' in scopeprint(x)x という名前が、その場所からは見つからないという意味です。
名前の打ち間違いか、定義する前に使っているのが典型です。
綴りを確認し、let x = ... のような定義を使う行より前に書いてください。
cannot convert value of type ‘String’ to specified type ‘Int’
error: cannot convert value of type 'String' to specified type 'Int'let s = "42"
let n: Int = sInt と宣言した場所に文字列を入れようとしています。
見た目が数字でも、"42" は文字列です。
let n: Int = Int(s)! のように変換してください。
value of optional type ‘String?’ must be unwrapped
error: value of optional type 'String?' must be unwrapped to a value of type 'String'let line: String = readLine()readLine() が返すのは String ではなく、オプショナルの String? です。
競プロでは入力が必ずあるとみなし、readLine()! と ! を付けて使います。
binary operator ‘+’ cannot be applied (‘String’ と ‘Int’)
error: binary operator '+' cannot be applied to operands of type 'String' and 'Int'let line = readLine()!
let n = line + 1読み込んだ入力を、文字列のまま計算に使っています。
let n = Int(line)! + 1 のように、先に整数へ変換してください。
binary operator ‘+’ cannot be applied (‘Int’ と ‘Double’)
error: binary operator '+' cannot be applied to operands of type 'Int' and 'Double'let a = 3
let b = 1.5
print(a + b)Swift は Int と Double を自動では混ぜてくれません。
Double(a) + b のように、どちらかの型へそろえてから計算してください。
cannot assign to value: ‘x’ is a ’let’ constant
error: cannot assign to value: 'x' is a 'let' constantlet x = 1
x = 2let で作った定数に、あとから代入しようとしています。
書き換えたい値は var x = 1 と var で宣言してください。
cannot convert value of type ‘String.SubSequence’
error: cannot convert value of type 'String.SubSequence' (aka 'Substring') to expected argument type 'String'let parts = readLine()!.split(separator: " ")
var names = [String]()
names.append(parts[0])split が返す要素は String ではなく、Substring という別の型です。
String が必要な場所では String(parts[0]) のように包み直してください。
missing return in global function
error: missing return in global function expected to return 'Int'func add(_ a: Int, _ b: Int) -> Int {
let c = a + b
}戻り値の型を宣言した関数なのに、値を返さずに終わる経路があります。
return c のように、結果を return で返してください。
Program crashed: Illegal instruction(実行時・添字の範囲外)
*** Program crashed: Illegal instruction at 0x... ***
Thread 0 "main" crashed:
0 [inlined] [system] 0x... specialized Array.subscript.getter in main at //<compiler-generated>
1 0x... main + ... in main at /work/main.swift:2:8let a = [1, 2, 3]
print(a[3])配列の範囲外を添字で読もうとしています。
原因の 1 行は出ませんが、バックトレースの Array.subscript.getter が添字の読み取りを指しています。
要素数 3 の配列で使えるのは a[0] から a[2] までです。
ループの終了条件と、添字の最大値を見直してください。
Swift runtime failure: Unexpectedly found nil(実行時)
*** Swift runtime failure: Unexpectedly found nil while unwrapping an Optional value ***let a = Int(readLine()!)!
let b = Int(readLine()!)!! を付けた場所に、中身のない値(nil)が来ました。
2 行読むコードに 1 行しか入力していないなど、読む回数と入力の行数のずれが典型です。
3 5 のような 1 行を丸ごと Int(...) に渡したときも、変換に失敗して同じエラーになります。
入力欄の内容と、問題の入力形式を見比べてください。
Swift runtime failure: arithmetic overflow(実行時)
*** Swift runtime failure: arithmetic overflow ***let a = Int(readLine()!)!
print(a * a)計算結果が Int の範囲(約 ±9.2×10^18)を超えました。
答えが範囲に収まる問題でも、途中の掛け算で溢れることがあります。
制約から途中経過の最大値を見積もり、計算の順序を見直してください。
Swift runtime failure: Range requires lowerBound <= upperBound(実行時)
*** Swift runtime failure: Range requires lowerBound <= upperBound ***let n = Int(readLine()!)!
for i in 1...n { print(i) }1...n の n が 0 のように、範囲の右端が左端より小さくなりました。
... は右端が左端以上でないと作れません。
n が 0 になりうるなら、stride(from: 1, through: n, by: 1) を使うか、if n >= 1 で囲んでください。