Code Fix

中級

interface conversion panic の原因と直し方

型アサーション v.(T) は、vの実際の型がTでない場合に実行時パニックを起こします。2つ目の戻り値(ok)を受け取らずに単一戻り値の形で書くと、失敗時にそのままパニックします。

エラーメッセージの読み方

panic: interface conversion: interface {} is string, not int
panic
パニック — 実行時に回復不能な状態になったことを示します。deferとrecoverで捕まえない限り、そのままプロセスが終了します
interface conversion: interface {} is string, not int
詳細メッセージ — どの値が問題だったか

このエラーが出る典型パターン

パターン1

 1  package main
 2  
 3  import "fmt"
 4  
 5  func main() {
 6  	var i interface{} = "hello"
                            ^
 7  	n := i.(int)
 8  	fmt.Println(n)
 9  }
panic: interface conversion: interface {} is string, not intiの実際の型はstring

単一戻り値の形の型アサーションi.(int)は、iの実際の型がintでなければその場でパニックします。

直し方: "hello"42 にします。

この問題を解いてみる →

広告
広告スロット(未設定)

パターン2

 1  package main
 2  
 3  import "fmt"
 4  
 5  func main() {
 6  	var i interface{} = true
                           ^
 7  	n := i.(int)
 8  	fmt.Println(n)
 9  }
panic: interface conversion: interface {} is bool, not intiの実際の型はbool

boolを格納したinterfaceに対してintへの型アサーションを行うと、実際の型がbool, not intとしてパニックします。

直し方: true42 にします。

この問題を解いてみる →

パターン3

 1  package main
 2  
 3  import "fmt"
 4  
 5  func main() {
 6  	var i interface{} = 3.14 
                           ^
 7  	n := i.(int)
 8  	fmt.Println(n)
 9  }
panic: interface conversion: interface {} is float64, not intiの実際の型はfloat64

数値同士に見えてもfloat64とintは別の型で、暗黙の変換はされず型アサーションは失敗します。

直し方: 3.1442 にします。

この問題を解いてみる →

パターン4

 1  package main
 2  
 3  import "fmt"
 4  
 5  func main() {
 6  	var i interface{} = []int{1, 2}
                              ^
 7  	n := i.(int)
 8  	fmt.Println(n)
 9  }
panic: interface conversion: interface {} is []int, not intiの実際の型は[]int

スライスをintに変換しようとするような明らかな型違いでも、コンパイルは通ってしまい実行時に発覚します。

直し方: []int{1, 2}42 にします。

この問題を解いてみる →

パターン5

 1  package main
 2  
 3  import "fmt"
 4  
 5  func main() {
 6  	var i interface{} = int64(5)
                             ^
 7  	n := i.(int)
 8  	fmt.Println(n)
 9  }
panic: interface conversion: interface {} is int64, not intiの実際の型はint64

int64とintは同じ「整数」でもGoでは別の型として区別され、型アサーションはint64, not intとして失敗します。

直し方: int64(5)42 にします。

この問題を解いてみる →

よくある誤解

「型が違っていても、アサーションはゼロ値を返してくれるはず」という思い込みは誤りです。単一戻り値の形の型アサーションは失敗時にパニックするため、失敗しうる場合はv, ok := v.(T)の形でokを確認する必要があります。

まとめ

interface conversion panicは中級でつまずきやすい項目です。上の5パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。

演習をはじめる

関連するエラー

広告
広告スロット(未設定)