配列の添字に間違って文字列を渡した場合、プログラミング言語ごとにどういうエラーメッセージになるのかを調べてみた。
先に結論:エラーメッセージが読みやすかったランキング
同じエラー原因に対してどの言語のエラーメッセージが読みやすかったかを個人的に順位付けしてみた。
順位 | 言語名 | 理由 |
---|---|---|
1位 | Python | 「リストの添字でエラーが起きている」と原因を教えてくれる、SyntaxWarningで「コンマの書き忘れ?」と提案してくれる、さらにエラーメッセージが色付きで分かりやすいと至れり尽くせり |
2位 | Swift | エラーメッセージは「型が合わない」で他と似たりよったりだが、「じゃあ何ならよかったのか」の候補を複数提案してくれる |
同率3位 | Java | 「StringはIntに変換できない」というKotlinやRubyとほぼ同じエラーメッセージ |
同率3位 | Kotlin | 同上。JavaやRubyとほぼ同じエラーメッセージ |
5位 | Ruby | 「StringをIntに変換できない」というエラーメッセージはJavaやKotlinと同じだが、「暗黙の」という少し呪文めいた単語の意味が分かりづらい |
6位 | Golang | ASCIIコードを示されるだけで、何がエラーの原因なのか分かりづらい |
評価対象外 | Perl | エラーが起きない |
Golang
package main
func main() {
ary := [1]int{1}
_ = ary['0']
}
結果
「48という添字(文字列'0'のASCIIコード)は範囲外である」という、低レイヤー寄りのエラーメッセージ。
# command-line-arguments
./array.go:4:11: invalid argument: index 48 out of bounds [0:1]
Java
public class Main {
public static void main(String[] args) {
int[] ary = {1};
int n = ary["0"];
}
}
結果
「Stringはintに変換できない」というエラーメッセージ。エラー箇所のコードも教えてくれる。
Main.java:4: error: incompatible types: String cannot be converted to int
int n = ary["0"];
^
1 error
Kotlin
fun main(){
val ary = intArrayOf(1)
ary["0"]
}
結果
「Stringが渡されているが、Intが渡されるべき」というエラーメッセージ。エラー箇所のコードも教えてくれる。
Main.kt:3:7: error: type mismatch: inferred type is String but Int was expected
ary["0"]
^
Perl
エラーは起きない
(1)["0"];
Python
[1]['0']
結果
「リストの添字にはstrではなくintまたはスライスが渡されるべき」というエラーメッセージ。エラー箇所のコードも教えてくれる。
エラーとは別にSyntaxWarningも表示される。さらに、実際のエラーメッセージは色付きで読みやすい
/path/array.py:2: SyntaxWarning: list indices must be integers or slices, not str; perhaps you missed a comma?
[1]['0']
Traceback (most recent call last):
File "/path/array.py", line 2, in <module>
[1]['0']
~~~^^^^^
TypeError: list indices must be integers or slices, not str
Ruby
[1]['0']
結果
「StringからIntegerへの暗黙の変換はしない」というエラーメッセージ。エラー箇所のコードも教えてくれる。
array.rb:2:in 'Array#[]': no implicit conversion of String into Integer (TypeError)
[1]['0']
^^^
from array.rb:2:in '<main>'
Swift
let ary = [1]
let _ = ary["0"]
結果
「サブスクリプト(Swiftでの添字)の呼び出しが一致しない」というエラーメッセージ。エラー箇所のコードも教えてくれる。
さらに、「渡されるべきだった値の候補」をいくつか列挙してくれる。
main.swift:2:12: error: no exact matches in call to subscript
let _ = ary["0"]
^
Swift.Array:16:23: note: candidate expects value of type 'Int' for parameter #1 (got 'String')
@inlinable public subscript(index: Int) -> Element { get set }
^
Swift.Array:17:23: note: candidate expects value of type 'Range<Int>' for parameter #1 (got 'String')
@inlinable public subscript(bounds: Range<Int>) -> ArraySlice<Element> { get set }
^
Swift.Collection:3:23: note: candidate expects value of type '(UnboundedRange_) -> ()' for parameter #1 (got 'String')
@inlinable public subscript(x: (UnboundedRange_) -> ()) -> Self.SubSequence { get }
^
Swift.MutableCollection:3:23: note: candidate expects value of type '(UnboundedRange_) -> ()' for parameter #1 (got 'String')
@inlinable public subscript(x: (UnboundedRange_) -> ()) -> Self.SubSequence { get set }
^