配列の添字に間違って文字列を渡した場合のエラーメッセージ

配列の添字に間違って文字列を渡した場合、プログラミング言語ごとにどういうエラーメッセージになるのかを調べてみた。


## 先に結論：エラーメッセージが読みやすかったランキング

同じエラー原因に対してどの言語のエラーメッセージが読みやすかったかを個人的に順位付けしてみた。

| 順位 | 言語名 | 理由 |
| ---- | ---- | ---- |
| 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

```go
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

```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

```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

エラーは起きない

```perl
(1)["0"];
```






## Python

```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

```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

```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 }
                      ^
```