【Go】cannot use x (variable of type int) as float64 value in argument to math.Absの原因と対処法

目次

はじめに

この記事ではGo言語でmath.Absを使う際に遭遇しがちなcannot use x (variable of type int) as float64 value in argument to math.Absというエラーの原因と対処法をまとめます。

Rubyなど、整数や小数を自動的に型変換してくれる言語に慣れていると、Go言語の型変換ルールに戸惑うかもしれません。

今回のエラーを解決しながら、Go言語の型付けを理解するきっかけにしていきましょう。

エラーの内容と原因

Go言語で整数型intをそのままmath.Absに渡すと、次のエラーが出ます。

cannot use x (variable of type int) as float64 value in argument to math.Abs

たとえば以下のようなコードです。

main.go
package main

import (
	"fmt"
	"math"
)

func main() {
	num1, num2 := -10, 5
	x := num1 + num2


	sum := math.Abs(x) // ここでエラーが発生
	fmt.Println(sum)
}

これはmath.Absが引数としてfloat64型を要求しているため、int型であるxをそのまま渡すと型が合わずコンパイルエラーになるのです。

解決策

大きく次の2つが考えられます。

1. float64へ型変換

以下のように明示的にfloat64へ型変換すればエラーを解消できます。

Go
package main

import (
	"fmt"
	"math"
)

func main() {
	num1, num2 := -10, 5
	x := num1 + num2

	sum := math.Abs(float64(x)) // 引数を float64 型に変換
	fmt.Println(sum)
}

上記のコードを実行すると問題なく5が出力されます。

これでエラーは解消です。

2. math.Absを使わずif文で絶対値を求める(代替方法)

math.Absを使わずとも、条件分岐で絶対値を求めることも可能です。

main.go
package main

import (
	"fmt"
)

func main() {
	num1, num2 := -10, 5
	x := num1 + num2

	var sum int
	if x < 0 {
		// x がマイナスの場合は符号を反転
		sum = -x
	} else {
		sum = x
	}

	fmt.Println(sum)
}

こちらでも問題なく5が出力されます。

Go言語の型付けを深掘り

ここからは今回の問題に関連して、Goの型付けのルールをもう少し詳しく確認します。

エラーにならないケース

次のように-10 + 5を引数として直接math.Absに渡した場合はコンパイルエラーになりません。

main.go
package main

import (
	"fmt"
	"math"
)

func main() {
	// num1, num2 := -10, 5
	// x := num1 + num2

	sum := math.Abs(-10 + 5) // 変数を使わず引数として直接 -10 + 5 を渡す
	fmt.Println(sum)
}

Goにおいて、-10 + 5そのものは「型付けされていない定数(untyped constant) 」として扱われるからです。

型付けされていない定数

型付けされていない定数とは、「まだ具体的な型が確定してない状態の定数」を表す概念です。

※Goにおいて、定数とは単に「変化しない単純な値」のことを指します。

この型付けされていない定数は、使用される文脈に基づいて適切な型に変換されます。

今回の場合、sum := math.Abs(-10 + 5)と書いた時に初めて-10 + 5の型が確定します。

math.Absfloat64型を求めるため、-10 + 5float64として解釈されるのです。

これは暗黙的な型変換とは異なり、Goの定数の型付けルールの一部です。

エラーになるケース

一方で、事前に変数へ代入してしまうとその時点で型がintで確定します。

	num1, num2 := -10, 5
	x := num1 + num2 // x は int

このxmath.Absに渡そうとすると型がマッチせずコンパイルエラーを起こすのです。

変数に代入された時点で具体的な型(この場合はint)が確定し、以降は他の型への自動変換は行われません。

そのため変数xmath.Absで使用する場合は、明示的にfloat64(x)という型変換が必要になります。

まとめ

  • math.Absは引数にfloat64型を求めるため、int型の値を渡す場合は型変換が必要
  • Goにおいて型付けされていない定数は文脈に応じて適切な型に変換される

この記事のとおりに対応すればエラーは解消できるかなと思います。

後半のGoの型付けについてもこの機会に理解しておくと役立つ時があるはずです。

Rubyの場合、整数や小数を自動で型変換してくれるため、Go言語の学習においてはこの手のつまずきに今後も遭遇しそうです。

1つずつものにしていきましょう。

最後に、記事の内容に誤りがある場合、コメントにて教えていただけますと幸いです。

参考資料

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

未経験でSESから従業員300名以上の自社開発企業に転職しました。業務や個人開発で直面した問題や、転職・学習の経験を発信していきます。

コメント

コメントする

目次