今回はgolangで「cannot use ~」というエラーが出たときの原因と解決策について紹介していきます。
golangで「cannot use ~」というエラーが出た
golangで開発を行っていると「cannot use ~」というエラーに遭遇することがあります。
基本的には関数への変数の引き渡し時に型が一致していなかったり、渡せない変数を渡そうとしていることで発生するエラーとなりますが、発生するシチュエーションが結構多くあるのでそれぞれ細かく原因と対処法について説明していきます。
「cannot use ~」の原因と対処法
変数に異なる型の値を代入
最初に定義された変数の型に別の型の値を入れようとすると「cannot use ~」というエラーが発生します。
最初に変数aをint型として定義していますが、次の行にstringで”hogehoge”を代入しようとしています。
func main() {
var a int
a = "hogehoge"
fmt.Println(a)
}
このコードを実行すると以下のエラーが発生します。
型が一致しないために”hogehoge”を使用することができないという旨のエラーメッセージが表示されています。
main.go:7:6: cannot use "hogehoge" (untyped string constant) as int value in assignment (exit status 1)
どうしても変数aに文字列を代入したい場合は変数aをint→stringにキャスト(型変換)してあげる必要があります。
func main() {
var a int
b := strconv.Itoa(a)
b = "hogehoge"
fmt.Println(b)
}
strconv.Itoa()関数を使うことでintからstringへキャストできるので、変数aに文字列を代入することができるようになりました。
このコードの実行結果はhogehogeとなります。
引数にポインタを渡せていない
次に引数にポインタを渡せていない場合についてです。
print()関数では引数としてint型のポインタを期待していますが、実際にはint型の値を渡しています。この場合も「cannot use ~」エラーが発生します。
func main() {
a := 1
print(a)
}
func print(a *int) {
fmt.Println(*a)
}
実行結果のエラーは以下となります。
main.go:7:8: cannot use a (variable of type int) as *int value in argument to print (exit status 1)
このエラーを解消するには変数の値ではなく、値のポインタを渡します。
func main() {
a := 1
print(&a)
}
func print(a *int) {
fmt.Println(*a)
}
このように実装することでaのポインタの値を参照できるようになるため1が出力されます。
関数でnilを返却しようとしている
戻り値の型が決まっているにもかかわらずnilを返そうとすると「cannot use ~」が発生します。
func main() {
a := 1
increment(&a)
fmt.Println(a)
}
func increment(a *int) int {
*a++
return nil
}
以下のようにint型を期待している戻り値に対してnillを返そうとしてエラーになっています。
main.go:13:9: cannot use nil as int value in return statement (exit status 1)
戻り値にnilを許容したい場合は戻り値をポインタにするとこのエラーを解消することができます。
func main() {
a := 1
increment(&a)
fmt.Println(a)
}
func increment(a *int) *int {
*a++
return nil
}
変数_を参照している
戻り値が二つある状態で片方をアンダースコア(_)にして、そのアンダースコアの変数を参照しようとすると「cannot use ~」が発生します。
func main() {
a, _ := strconv.Atoi("1")
fmt.Println(a)
fmt.Println(_)
}
アンダースコアを使うと戻り値を握り潰してしまい、値を参照することはできません。
main.go:11:14: cannot use _ as value or type (exit status 1)
戻り値を二つとも参照したい場合はアンダースコアで握り潰さずに二つとも受け取りましょう。
func main() {
a, err := strconv.Atoi("1")
fmt.Println(a)
fmt.Println(err)
}
golangをもっと詳しくなりたい方に
golang学習のために筆者が実際に受講したUdemy教材をまとめています。
golang学習のために筆者が実際に読んでおすすめしたい本をまとめています。